CSV 数据清洗技巧:面向分析师和开发者
CSV 文件是表格数据的通用交换格式。它们简单、人类可读,且被从 Excel 到 pandas 的每个工具支持。但现实世界中的 CSV 文件往往很混乱——编码不一致、缺失值、混合数据类型和格式错误的行。本指南涵盖了可靠清洗 CSV 数据的实用技巧。
常见 CSV 问题
1. 编码问题
最令人沮丧的 CSV 问题是编码。在 Windows 上用 Excel 创建的文件可能使用 windows-1252,而你的 Python 脚本期望的是 utf-8。
症状:乱码(mojibake),如 é 代替 é,或 UnicodeDecodeError 异常。
检测:
import chardet
with open('data.csv', 'rb') as f:
result = chardet.detect(f.read(10000))
print(result) # {'encoding': 'Windows-1252', 'confidence': 0.73}
修复:使用检测到的编码读取,然后保存为 UTF-8:
import pandas as pd
df = pd.read_csv('data.csv', encoding='windows-1252')
df.to_csv('data_clean.csv', encoding='utf-8', index=False)
2. 分隔符不一致
并非所有"CSV"都使用逗号。欧洲的 CSV 文件通常使用分号,因为逗号在许多欧洲语言中是小数分隔符。
# 自动检测分隔符
import csv
with open('data.csv', 'r') as f:
dialect = csv.Sniffer().sniff(f.read(5000))
print(f"Delimiter: {repr(dialect.delimiter)}")
我们的 CSV 编辑器 自动处理分隔符检测——粘贴你的数据,它会识别格式。
3. 缺失值
缺失数据以多种形式出现:空单元格、NA、N/A、null、-,或仅仅是空白。
# 标准化所有缺失值表示
df = pd.read_csv('data.csv', na_values=['NA', 'N/A', 'null', '-', '', ' '])
# 检查每列的缺失值
print(df.isnull().sum())
# 策略 1:删除关键字段缺失的行
df = df.dropna(subset=['email', 'name'])
# 策略 2:填充默认值
df['country'] = df['country'].fillna('Unknown')
# 策略 3:前向填充(时间序列)
df['price'] = df['price'].ffill()
4. 重复行
精确重复容易发现。模糊重复(同一个人名字拼写略有不同)则更难。
# 查找精确重复
duplicates = df[df.duplicated(keep=False)]
print(f"Found {len(duplicates)} duplicate rows")
# 删除重复,保留第一次出现
df = df.drop_duplicates()
# 根据特定列删除重复
df = df.drop_duplicates(subset=['email'], keep='last')
5. 数据格式不一致
日期格式混乱、电话号码有无国家代码不一致、大小写不统一:
# 标准化日期
df['date'] = pd.to_datetime(df['date'], format='mixed', dayfirst=False)
# 标准化文本字段
df['name'] = df['name'].str.strip().str.title()
df['email'] = df['email'].str.strip().str.lower()
# 标准化电话号码(基础版)
df['phone'] = df['phone'].str.replace(r'[^0-9+]', '', regex=True)
6. 数据类型问题
CSV 将所有内容存储为文本。带前导零的数字、邮政编码和电话号码在解析时可能丢失格式:
# 保留邮政编码的前导零
df = pd.read_csv('data.csv', dtype={'zip_code': str, 'phone': str})
# 将货币字符串转换为数字
df['price'] = df['price'].str.replace('$', '').str.replace(',', '').astype(float)
清洗后的验证
始终验证清洗后的数据:
# 检查行数(是否意外丢失或增加了行?)
print(f"Rows: {len(df)}")
# 检查数据类型
print(df.dtypes)
# 检查值范围
print(df.describe())
# 检查剩余的空值
print(df.isnull().sum())
# 验证唯一性约束
assert df['email'].is_unique, "Duplicate emails found!"
命令行工具
无需编写代码进行快速清洗:
# 转换编码
iconv -f WINDOWS-1252 -t UTF-8 input.csv > output.csv
# 排序并删除重复行
sort -u input.csv > output.csv
# 提取特定列(cut)
cut -d',' -f1,3,5 input.csv > output.csv
# 过滤行(awk)
awk -F',' '$3 > 100' input.csv > filtered.csv
对于更复杂的转换,csvkit 等工具提供了完整的 CSV 工具套件:
# 安装
pip install csvkit
# 查看列名
csvcut -n data.csv
# 过滤行
csvgrep -c country -m "USA" data.csv > usa_only.csv
# 转换为 JSON
csvjson data.csv > data.json
在 CSV 和 JSON 之间转换?我们的 CSV 转 JSON 转换器 可以即时处理。
常见问题
CSV 处理的最大文件大小是多少?
CSV 格式本身没有固有限制。实际限制取决于你的工具:Excel 处理约 100 万行,pandas 在有足够 RAM 的情况下可以处理到几 GB,Dask 或 Polars 等工具可以处理超出内存的数据集。对于基于浏览器的工具,我们的 CSV 编辑器可处理最大 100MB 的文件。
我应该使用 CSV 还是 JSON 进行数据交换?
CSV 最适合扁平的表格数据(电子表格、数据库导出、简单列表)。JSON 更适合嵌套的层级数据(API 响应、配置、结构多变的文档)。详细比较请参阅我们的 CSV vs JSON vs XML 指南。
相关资源
- CSV 编辑器 — 在浏览器中编辑和清洗 CSV 数据
- CSV 转 JSON 转换指南 — 格式之间的转换
- JSON 格式化最佳实践 — 处理 JSON 输出