【Python10年经验总结】第二课 电商平台销售数据分析实践分解 – 数据清洗(Data Cleaning)
下面我们将展示如何处理这些常见的数据清洗任务。假设我们有一个包含销售订单数据的DataFrame,并逐步应用这些清洗操作。
常见用的分析场景:
处理缺失值并删除无效订单
去除重复订单记录
标准化时间格式(如“2025-06-01”)
清洗非标准金额字段(如包含货币符号)
矫正错误的产品ID或品类编码
填充空值(使用均值、众数或向前填充)
过滤掉测试订单或异常用户数据
对数值型字段进行类型转换(str → float)
拆分地址字段为省市区三级维度
删除无意义字段(如临时调试列)
首先,让我们创建一个示例DataFrame来模拟原始数据:
import pandas as pd
import numpy as np
# 创建示例DataFrame
data = {
'order_id': [1, 2, 3, 4, 5, 6, 7, 8],
'product_id': ['A001', 'B002', None, 'D004', 'E005', 'F006', 'G007', 'H008'],
'category_code': ['C1', 'C2', 'C1', 'C3', 'C4', 'C5', 'C6', 'C7'],
'amount': ['$100.00', '$200.00', '$300.00', None, '$500.00', '$600.00', '$700.00', '$800.00'],
'order_date': ['2025-06-01', '2025-06-02', '2025-06-03', '2025-06-04', '2025-06-05', '2025-06-06', '2025-06-07', '2025-06-08'],
'customer_id': [101, 102, 103, 104, 105, 106, 107, 108],
'address': ['Beijing, China', 'Shanghai, China', 'Guangzhou, China', 'Shenzhen, China', 'Hangzhou, China', 'Chengdu, China', 'Nanjing, China', 'Wuhan, China'],
'test_order': [False, True, False, False, False, False, False, False],
'debug_col': [None, None, None, None, None, None, None, None]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
接下来,我们将逐个处理上述提到的数据清洗任务。
1. 处理缺失值并删除无效订单
假设product_id
为空或amount
为空的订单是无效的。
# 删除无效订单
df_cleaned = df.dropna(subset=['product_id', 'amount'])
print("\n处理缺失值后:")
print(df_cleaned)
2. 去除重复订单记录
# 去除重复订单记录
df_cleaned = df_cleaned.drop_duplicates()
print("\n去除重复订单记录后:")
print(df_cleaned)
3. 标准化时间格式(如“2025-06-01”)
# 转换order_date为日期格式
df_cleaned['order_date'] = pd.to_datetime(df_cleaned['order_date'], format='%Y-%m-%d')
print("\n标准化时间格式后:")
print(df_cleaned)
4. 清洗非标准金额字段(如包含货币符号)
# 移除金额中的美元符号并转换为浮点数
df_cleaned['amount'] = df_cleaned['amount'].str.replace('$', '').astype(float)
print("\n清洗非标准金额字段后:")
print(df_cleaned)
5. 矫正错误的产品ID或品类编码
假设我们需要将所有产品ID转换为大写形式。
# 将product_id转换为大写
df_cleaned['product_id'] = df_cleaned['product_id'].str.upper()
print("\n矫正错误的产品ID后:")
print(df_cleaned)
6. 填充空值(使用均值、众数或向前填充)
这里我们用均值填充amount
列的空值。
# 使用均值填充amount列的空值
df_cleaned['amount'].fillna(df_cleaned['amount'].mean(), inplace=True)
print("\n填充空值后:")
print(df_cleaned)
7. 过滤掉测试订单或异常用户数据
假设我们要过滤掉test_order
为True的订单。
# 过滤掉测试订单
df_cleaned = df_cleaned[df_cleaned['test_order'] == False]
print("\n过滤掉测试订单后:")
print(df_cleaned)
8. 对数值型字段进行类型转换(str → float)
在这个例子中,amount
已经被转换为float,所以这一步已经在前面完成了。
9. 拆分地址字段为省市区三级维度
假设地址格式为“城市, 国家”,我们可以拆分为两个新列。
# 拆分address字段为city和country
df_cleaned[['city', 'country']] = df_cleaned['address'].str.split(', ', expand=True)
print("\n拆分地址字段后:")
print(df_cleaned)
10. 删除无意义字段(如临时调试列)
# 删除无意义字段
df_cleaned = df_cleaned.drop(columns=['debug_col'])
print("\n删除无意义字段后:")
print(df_cleaned)
综合以上步骤,最终的清理后的DataFrame如下:
这段代码展示了从原始数据到经过全面清洗的数据的过程。你可以根据实际需求调整每一步的操作。
import pandas as pd
import numpy as np
# 创建示例DataFrame
data = {
'order_id': [1, 2, 3, 4, 5, 6, 7, 8],
'product_id': ['A001', 'B002', None, 'D004', 'E005', 'F006', 'G007', 'H008'],
'category_code': ['C1', 'C2', 'C1', 'C3', 'C4', 'C5', 'C6', 'C7'],
'amount': ['$100.00', '$200.00', '$300.00', None, '$500.00', '$600.00', '$700.00', '$800.00'],
'order_date': ['2025-06-01', '2025-06-02', '2025-06-03', '2025-06-04', '2025-06-05', '2025-06-06', '2025-06-07', '2025-06-08'],
'customer_id': [101, 102, 103, 104, 105, 106, 107, 108],
'address': ['Beijing, China', 'Shanghai, China', 'Guangzhou, China', 'Shenzhen, China', 'Hangzhou, China', 'Chengdu, China', 'Nanjing, China', 'Wuhan, China'],
'test_order': [False, True, False, False, False, False, False, False],
'debug_col': [None, None, None, None, None, None, None, None]
}
df = pd.DataFrame(data)
# 删除无效订单
df_cleaned = df.dropna(subset=['product_id', 'amount'])
# 去除重复订单记录
df_cleaned = df_cleaned.drop_duplicates()
# 转换order_date为日期格式
df_cleaned['order_date'] = pd.to_datetime(df_cleaned['order_date'], format='%Y-%m-%d')
# 移除金额中的美元符号并转换为浮点数
df_cleaned['amount'] = df_cleaned['amount'].str.replace('$', '').astype(float)
# 将product_id转换为大写
df_cleaned['product_id'] = df_cleaned['product_id'].str.upper()
# 使用均值填充amount列的空值
df_cleaned['amount'].fillna(df_cleaned['amount'].mean(), inplace=True)
# 过滤掉测试订单
df_cleaned = df_cleaned[df_cleaned['test_order'] == False]
# 拆分address字段为city和country
df_cleaned[['city', 'country']] = df_cleaned['address'].str.split(', ', expand=True)
# 删除无意义字段
df_cleaned = df_cleaned.drop(columns=['debug_col', 'address', 'test_order'])
print("最终清理后的数据:")
print(df_cleaned)