别光看教程了!用Pandas处理真实CSV数据,从读取到清洗保姆级实战
2026/5/8 10:32:39 网站建设 项目流程

别光看教程了!用Pandas处理真实CSV数据,从读取到清洗保姆级实战

每次打开数据分析教程,看到的总是完美无缺的示例数据——整齐的列名、标准的格式、毫无缺失值。但当你兴冲冲地下载了一份真实业务数据准备大展身手时,迎面而来的可能是乱码的列名、混杂的数据类型、莫名其妙的缺失值标记。这才是真实世界的数据分析起点。

本文将带你用Pandas处理一份真实的电商销售数据CSV文件(模拟真实业务场景),从文件读取到完成基础清洗,全程使用实际工作中最常见的操作链。你会发现,真实数据处理的核心不在于复杂算法,而在于如何高效解决那些教程从不提及的"脏活累活"

1. 准备:认识我们的"不完美"数据

我们从模拟的电商平台导出2023年Q4销售数据(sales_data.csv),用文本编辑器打开能看到以下典型问题:

order_id,order_date,customer_id,product_name,product_category,quantity,unit_price,payment_method,delivery_status 1001,2023-10-02,C-1025,无线蓝牙耳机,电子产品,2,299.0,信用卡,已送达 1002,2023-10-05,C-1083,"智能手机,旗舰款",电子产品,1,null,支付宝,运输中 1003,2023-10-07,C-1002,棉质T恤,服装,3,89.5,微信支付,已取消 1004,2023-10-12,C-1156,不锈钢保温杯,家居,null,159.0,信用卡,已送达 ...

这份数据至少存在7类常见问题:

  • 混合数据类型(数值/字符串)
  • 缺失值(null/空值)
  • 商品名称含特殊字符(逗号)
  • 列名风格不统一(下划线vs驼峰)
  • 日期非标准格式
  • 金额单位不统一
  • 状态字段值不规范

提示:真实数据往往比教程示例复杂得多。建议先用文本编辑器快速浏览原始文件,对数据问题建立整体认知。

2. 数据加载:避开那些新手常踩的坑

2.1 智能读取CSV文件

import pandas as pd # 最佳实践:首次读取时保留原始数据副本 raw_df = pd.read_csv('sales_data.csv', keep_default_na=False, dtype={'customer_id': str}) clean_df = raw_df.copy()

关键参数解析:

  • keep_default_na=False:防止Pandas自动转换各种空值标记
  • dtype参数:强制指定列数据类型,避免自动推断错误

常见读取问题解决方案:

问题类型解决方案参数示例
编码问题指定文件编码encoding='gbk''utf-8'
日期解析明确日期列parse_dates=['order_date']
千分位数字指定千分位符thousands=','
评论符号忽略特定行comment='#'

2.2 首次数据快照

查看数据概览时,避免直接使用head(),而是采用组合策略:

def quick_scan(df): print(f"数据集形状: {df.shape}") print("\n前3行样本:") print(df.head(3)) print("\n随机5行样本:") print(df.sample(5, random_state=42)) print("\n数据类型检查:") print(df.dtypes) print("\n缺失值统计:") print(df.isna().sum()) quick_scan(clean_df)

3. 列级清洗:从混乱到规范

3.1 列名标准化

真实数据列名常有的问题:

  • 中英文混合
  • 大小写不一致
  • 包含空格/特殊字符
  • 过长的描述性名称
# 列名清洗函数 def clean_columns(df): df.columns = ( df.columns.str.lower() # 统一小写 .str.replace('[^a-z0-9_]', '_', regex=True) # 替换特殊字符 .str.replace('__+', '_', regex=True) # 合并连续下划线 .str.rstrip('_') # 去除尾部下划线 ) return df clean_df = clean_columns(clean_df)

处理前后对比:

原始列名清洗后列名
order_idorder_id
customer_idcustomer_id
product_nameproduct_name
product_categoryproduct_category
unit_priceunit_price

3.2 数据类型校正

典型问题处理方案:

  1. 数值列中的文本字符
clean_df['quantity'] = pd.to_numeric(clean_df['quantity'], errors='coerce')
  1. 日期列格式混乱
clean_df['order_date'] = pd.to_datetime( clean_df['order_date'], format='%Y-%m-%d', errors='coerce' )
  1. 分类数据标准化
status_mapping = { '已送达': 'delivered', '运输中': 'shipping', '已取消': 'cancelled' } clean_df['delivery_status'] = ( clean_df['delivery_status'] .map(status_mapping) .astype('category') )

4. 行级清洗:处理缺失值与异常值

4.1 智能处理缺失值

真实业务场景的缺失值处理策略:

# 分列处理缺失值 fill_strategy = { 'quantity': 1, # 数量默认为1 'unit_price': clean_df['unit_price'].median(), # 价格用中位数填充 'product_category': 'unknown', # 类别标记为未知 'payment_method': clean_df['payment_method'].mode()[0] # 用众数填充 } clean_df = clean_df.fillna(fill_strategy)

4.2 异常值检测与处理

构建数据质量检查报告:

def data_quality_report(df): report = pd.DataFrame({ 'dtype': df.dtypes, 'missing': df.isna().sum(), 'unique': df.nunique(), 'min': df.min(numeric_only=True), 'median': df.median(numeric_only=True), 'max': df.max(numeric_only=True) }) return report quality_report = data_quality_report(clean_df)

常见异常值处理方式:

  • 价格异常unit_price > 10000→ 设为中位数
  • 数量异常quantity < 0→ 取绝对值
  • 日期异常order_date < '2023-01-01'→ 标记为缺失

5. 高级清洗:处理文本与复合问题

5.1 商品名称中的陷阱

处理含分隔符的文本:

# 修复被错误分割的商品名称 clean_df['product_name'] = ( clean_df['product_name'] .str.replace('","', '|') # 替换内部逗号 .str.replace('"', '') # 去除引号 )

5.2 复合清洗管道

构建可复用的清洗管道:

def clean_pipeline(df): # 文本清洗 df = (df .pipe(clean_columns) .assign( product_name=lambda x: x['product_name'].str.replace('","', '|'), order_date=lambda x: pd.to_datetime(x['order_date']) )) # 数值处理 df = df.fillna(fill_strategy) df['unit_price'] = df['unit_price'].clip( lower=0.1, upper=df['unit_price'].quantile(0.99) ) return df clean_df = clean_pipeline(raw_df.copy())

6. 验证与保存清洗结果

6.1 数据质量验证

validation_rules = { 'order_id': lambda x: x.is_unique, 'customer_id': lambda x: x.str.startswith('C-').all(), 'quantity': lambda x: (x > 0).all(), 'unit_price': lambda x: (x.between(0.1, 10000)).all() } for col, rule in validation_rules.items(): assert rule(clean_df[col]), f"验证失败: {col}"

6.2 保存清洗后数据

最佳保存实践:

# 保存为压缩格式 clean_df.to_csv( 'cleaned_sales_data.csv.gz', index=False, compression='gzip', encoding='utf-8' ) # 同时保存处理日志 with open('cleaning_report.txt', 'w') as f: f.write(f"清洗时间: {pd.Timestamp.now()}\n") f.write(f"原始记录数: {len(raw_df)}\n") f.write(f"清洗后记录数: {len(clean_df)}\n") f.write("\n列名变更记录:\n") f.write(str(list(zip(raw_df.columns, clean_df.columns))))

7. 构建自动化清洗脚本

将完整流程封装为可重用脚本:

#!/usr/bin/env python3 """ sales_data_cleaner.py - 电商销售数据自动清洗脚本 """ import pandas as pd from pathlib import Path CONFIG = { 'input_encoding': 'utf-8', 'date_columns': ['order_date'], 'text_columns': ['product_name', 'product_category'], 'fill_rules': { 'quantity': 1, 'unit_price': 'median' } } def main(input_file, output_dir='clean_data'): """主清洗流程""" # 确保输出目录存在 Path(output_dir).mkdir(exist_ok=True) # 执行清洗 raw_df = pd.read_csv(input_file, **CONFIG) clean_df = clean_pipeline(raw_df) # 保存结果 output_file = Path(output_dir) / f'cleaned_{Path(input_file).name}' clean_df.to_csv(output_file, index=False) print(f"清洗完成!结果已保存到: {output_file}") if __name__ == '__main__': import sys main(sys.argv[1])

使用方式:

python sales_data_cleaner.py sales_data.csv

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询