CSV 数据读取错位问题分析与解决方案(以 Pandas 为例)

270 阅读2分钟

在使用 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')]

这种方式只能在读取之后清除问题,不如源头清洗更稳妥。