Python案例怎么清洗原始数据?

wen python案例 43

本文目录导读:

Python案例怎么清洗原始数据?

  1. 导入必要的库
  2. 加载原始数据
  3. 处理缺失值
  4. 处理重复值
  5. 处理异常值
  6. 数据类型转换
  7. 文本数据清洗
  8. 完整的清洗函数示例
  9. 保存清洗后的数据
  10. 可视化检查数据分布

Python中清洗原始数据是一个非常常见的任务,通常使用pandas库来完成,以下是一些最常见的清洗场景和对应的Python代码示例:

导入必要的库

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline  # 如果在Jupyter Notebook中

加载原始数据

# 从CSV文件加载
df = pd.read_csv('raw_data.csv')
# 查看数据的基本信息
print("数据形状:", df.shape)
print("\n前5行数据:")
df.head()
print("\n数据类型和缺失值:")
df.info()
print("\n描述性统计:")
df.describe(include='all')

处理缺失值

# 查看每列的缺失值数量
print(df.isnull().sum())
# 删除含有缺失值的行
df_cleaned = df.dropna()
# 删除特定列有缺失值的行
df_cleaned = df.dropna(subset=['重要列名'])
# 用特定值填充缺失值
df['列名'] = df['列名'].fillna(0)  # 填充0
df['列名'] = df['列名'].fillna(df['列名'].mean())  # 填充均值
df['列名'] = df['列名'].fillna(df['列名'].median())  # 填充中位数
df['列名'] = df['列名'].fillna(method='ffill')  # 用前一个值填充
df['列名'] = df['列名'].fillna(method='bfill')  # 用后一个值填充
# 对于分类数据,用众数填充
df['分类列'] = df['分类列'].fillna(df['分类列'].mode()[0])

处理重复值

# 检查重复行
print(f"重复行数量: {df.duplicated().sum()}")
# 查看重复行
df[df.duplicated()]
# 删除重复行
df_cleaned = df.drop_duplicates()
# 删除指定列的重复行
df_cleaned = df.drop_duplicates(subset=['列1', '列2'])
# 保留最后出现的重复行
df_cleaned = df.drop_duplicates(keep='last')

处理异常值

# 方法1:使用Z-score检测异常值
from scipy import stats
z_scores = np.abs(stats.zscore(df['数值列']))
df_cleaned = df[(z_scores < 3)]  # 保留Z-score小于3的数据
# 方法2:使用IQR(四分位距)检测异常值
Q1 = df['数值列'].quantile(0.25)
Q3 = df['数值列'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
df_cleaned = df[(df['数值列'] >= lower_bound) & (df['数值列'] <= upper_bound)]
# 方法3:用上下限值替换异常值(winsorize处理)
df['数值列'] = np.where(df['数值列'] < lower_bound, lower_bound, df['数值列'])
df['数值列'] = np.where(df['数值列'] > upper_bound, upper_bound, df['数值列'])

数据类型转换

# 转换数据类型
df['日期列'] = pd.to_datetime(df['日期列'])  # 转日期类型
df['数值列'] = pd.to_numeric(df['数值列'], errors='coerce')  # 转数值类型,无效值转为NaN
df['字符串列'] = df['字符串列'].astype(str)  # 转字符串类型
df['分类列'] = df['分类列'].astype('category')  # 转分类类型
# 处理数值列中的特殊字符
df['价格列'] = df['价格列'].str.replace('$', '').str.replace(',', '').astype(float)

文本数据清洗

# 去除空格
df['文本列'] = df['文本列'].str.strip()  # 去除前后空格
df['文本列'] = df['文本列'].str.replace(' ', '')  # 去除所有空格
# 统一大小写
df['文本列'] = df['文本列'].str.lower()  # 转小写
df['文本列'] = df['文本列'].str.upper()  # 转大写
# 替换特殊字符
df['文本列'] = df['文本列'].str.replace('[^a-zA-Z0-9]', '', regex=True)  # 只保留字母和数字
# 去除特定模式
df['文本列'] = df['文本列'].str.replace('\d+', '', regex=True)  # 去除数字

完整的清洗函数示例

def clean_data(df):
    """
    数据清洗函数
    """
    # 创建副本
    df_cleaned = df.copy()
    # 1. 删除完全重复的行
    df_cleaned = df_cleaned.drop_duplicates()
    # 2. 处理缺失值
    # 删除缺失值超过50%的列
    df_cleaned = df_cleaned.dropna(thresh=len(df_cleaned)*0.5, axis=1)
    # 数值列用中位数填充
    numeric_cols = df_cleaned.select_dtypes(include=[np.number]).columns
    for col in numeric_cols:
        df_cleaned[col].fillna(df_cleaned[col].median(), inplace=True)
    # 分类列用众数填充
    categorical_cols = df_cleaned.select_dtypes(include=['object']).columns
    for col in categorical_cols:
        df_cleaned[col].fillna(df_cleaned[col].mode()[0], inplace=True)
    # 3. 去除异常值(使用IQR方法)
    for col in numeric_cols:
        Q1 = df_cleaned[col].quantile(0.25)
        Q3 = df_cleaned[col].quantile(0.75)
        IQR = Q3 - Q1
        lower_bound = Q1 - 1.5 * IQR
        upper_bound = Q3 + 1.5 * IQR
        df_cleaned[col] = df_cleaned[col].clip(lower_bound, upper_bound)
    # 4. 重置索引
    df_cleaned.reset_index(drop=True, inplace=True)
    return df_cleaned
# 使用清洗函数
df_cleaned = clean_data(df)
print(f"\n清洗前数据量: {len(df)}")
print(f"清洗后数据量: {len(df_cleaned)}")
print(f"清洗掉的数据量: {len(df) - len(df_cleaned)}")

保存清洗后的数据

# 保存为CSV
df_cleaned.to_csv('cleaned_data.csv', index=False)
# 保存为Excel
df_cleaned.to_excel('cleaned_data.xlsx', index=False)

可视化检查数据分布

# 查看数值列的分布(洗前 vs 洗后)
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# 清洗前
axes[0].hist(df['数值列'], bins=30, edgecolor='black')
axes[0].set_title('清洗前')
# 清洗后
axes[1].hist(df_cleaned['数值列'], bins=30, edgecolor='black')
axes[1].set_title('清洗后')
plt.show()

这个完整的案例涵盖了数据清洗的各个方面,根据你的实际数据和需求,可以选择使用其中的某些部分,关键是要先了解数据的特点(通过df.info()df.describe()),然后针对性地进行清洗。

抱歉,评论功能暂时关闭!