在使用 pandas.read_csv() 读取 CSV 文件时,若某些行末尾多了一个逗号 , ,将导致数据列错位,常见表现为:
- 数据列数比表头多;
- 出现
Unnamed: x多余列; - 数据整体前移或后移;
- 某些字段为空,或者覆盖了其他字段。
❗ 1. 问题来源
以如下数据为例:
表头(共 7 列):
scss
复制编辑
记账时间,交易日期,收支类型,交易类型,操作金额(元),操作后余额(元),备注
第一行数据(错误的,末尾多了一个 ,,实际是 8 列):
2025-03-02 03:20:28,2025-03-01,支出,扣款,25.37,0.00,20250301现金消耗扣款,
这种写法会导致 pandas 将数据读取成 8 列,而你定义的列名只有 7 个,于是多出的字段会被命名为 Unnamed: 7,造成列错位或数据丢失。
✅ 2. 正确做法:读取前预处理数据
建议在读取前进行预处理,去除行尾多余逗号,确保每一行的字段数量一致。
✅ 示例代码(集成到你原来的逻辑中):
elif file_format == 'csv':
encoding = self._detect_encoding()
# Step 1:读取并清洗每一行,去掉尾部多余逗号
with open(self.file_path, 'r', encoding=encoding, errors='replace') as infile:
cleaned_lines = []
for line in infile:
line = line.rstrip('\n').rstrip(',') + '\n' # 先去换行再去逗号,再加回换行
cleaned_lines.append(line)
# Step 2:使用 StringIO 将清洗后的内容读入 pandas
from io import StringIO
cleaned_file = StringIO(''.join(cleaned_lines))
# Step 3:读取 CSV 数据
return pd.read_csv(
cleaned_file,
skiprows=skiprows,
delimiter=delimiter,
dtype=str,
keep_default_na=False,
on_bad_lines='skip'
)
📌 3. 其他可选方案
✅ 方案 A:强制限制列数
pd.read_csv(..., usecols=range(7))
这种方式适用于你已知 CSV 应该只有 7 列的情况下,但不推荐长期使用,因为它是“掩盖问题”,不是修复问题。
✅ 方案 B:读取后清除 Unnamed 列(不推荐,属于补救)
df = pd.read_csv(...)
df = df.loc[:, ~df.columns.str.contains('^Unnamed')]
这种方式只能在读取之后清除问题,不如源头清洗更稳妥。