You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pandas读取无表头CSV文件并保留第4列内空格的问题求解

需求说明

现有无表头CSV格式数据文件,无法重新生成,需使用pandas读取,且第4列包含的空格要完整保留。

最初尝试的读取代码

df = pd.read_csv('datasource.csv', sep='\s+', engine='python')

数据源样例

202001YYYY 0101   S5387140320101                FUSELA-CANAL18 aaaa   20200116AIT1206000016           201252552588252525          01 01002  8558569641      0010 0001  00002RATTR00000        170.00 0000000        340.00 109200217378
202001YYYY 0101   S5517000290210                FUSELA-CONICAL SERE   20200120AIT1206000117           214782523363200113          01 01002  8558569642      0010 0001  00008RATTR00000       2912.82 0000000      23302.56 109200229739
202001YYYY 0101   S5517000290210                FUSELA-CONICAL AZER   20200120AIT1206000118           296385241152200113          01 01002  8558569643      0010 0001  00003RATTR00000       2912.82 0000000       8738.46 109200233248
202001YYYY 0101   S5387140320101                FUSELAA               20200117AIT1206000020           201258963255558588          01 01002  8558569644      0010 0001  00003RATTR00000        170.00 0000000        510.00 109200217378
202001YYYY 0101   S5337500122202                FUSELA TYHNN          20200120AIT1206000119           201478933663636363          01 01002  8558569645      0010 0001  00003RATTR00000        814.41 0000000       2443.23 109200218022
202001YYYY 0101   S5337500122202                FUSELA RTGYU          20200120AIT1206000120           278965412333333625          01 01002  8558569646      0010 0001  00004RATTR00000        814.41 0000000       3257.64 109200222120
202001YYYY 0101   S5367140300400                FUSELAEE SERVICE DOOR 20200120AIT1206000129           202010048420200113          01 01002  9200235812      0010 0001  00001EAUSD00000       1700.00 0000000       1700.00 109200235812
202001YYYY 0101   S5517200000852                FUSELATYHJJ EDGE ASSY-LH20200117AIT1206000076         202010022320200110          01 01002  9200222563      0010 0001  00001EAUSD00000      10474.90 0000000      10474.90 109200222563

期望输出格式

name1      name2  name3           name4                 name5                  name6               name7 name9  name10          name11 name12 name13                name14 name15         name16 name17
202001YYYY 0101   S5387140320101  FUSELA-CANAL18 aaaa   20200116AIT1206000016  201252552588252525  01    01002  8558569641      0010   0001  00002RATTR00000        170.00 0000000        340.00 109200217378
202001YYYY 0101   S5517000290210  FUSELA-CONICAL SERE   20200120AIT1206000117  214782523363200113  01    01002  8558569642      0010   0001  00008RATTR00000       2912.82 0000000      23302.56 109200229739
202001YYYY 0101   S5517000290210  FUSELA-CONICAL AZER   20200120AIT1206000118  296385241152200113  01    01002  8558569643      0010   0001  00003RATTR00000       2912.82 0000000       8738.46 109200233248
202001YYYY 0101   S5387140320101  FUSELAA               20200117AIT1206000020  201258963255558588  01    01002  8558569644      0010   0001  00003RATTR00000        170.00 0000000        510.00 109200217378
202001YYYY 0101   S5337500122202  FUSELA TYHNN          20200120AIT1206000119  201478933663636363  01    01002  8558569645      0010   0001  00003RATTR00000        814.41 0000000       2443.23 109200218022
202001YYYY 0101   S5337500122202  FUSELA RTGYU          20200120AIT1206000120  278965412333333625  01    01002  8558569646      0010   0001  00004RATTR00000        814.41 0000000       3257.64 109200222120
202001YYYY 0101   S5367140300400  FUSELAEE SERVICE DOOR 20200120AIT1206000129  202010048420200113  01    01002  9200235812      0010   0001  00001EAUSD00000       1700.00 0000000       1700.00 109200235812
202001YYYY 0101   S5517200000852  FUSELATYHJJ EDGE ASSY-LH20200117AIT12060000  202010022320200110  01    01002  9200222563      0010   0001  00001EAUSD00000      10474.90 0000000      10474.90 109200222563

原有尝试代码

import re
import pandas as pd

data = {
  'c1': [],
  'c2': [],
  'c3': [],
  'c4': [],
  'c5': [],
  'c6': [],
  'c7': [],
  'c8': [],
  'c9': [],
  'c10': [],
  'c11': [],
  'c12': [],
  'c13': [],
  'c14': [],
  'c15': [],
  'c16': [],
  'c17':[],
}
with open('datasource.csv', 'r') as f:
    for line in f:
        c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17= re.split('\s+', line.strip())
        data['c1'].append(c1)
        data['c2'].append(c2)
        data['c3'].append(c3)
        data['c4'].append(' '.join(c4))
        data['c5'].append(c5)
        data['c6'].append(c6)
        data['c7'].append(c7)
        data['c8'].append(c8)
        data['c9'].append(c9)
        data['c10'].append(c10)
        data['c11'].append(c11)
        data['c12'].append(c12)
        data['c13'].append(c13)
        data['c14'].append(c14)
        data['c15'].append(c15)
        data['c16'].append(c16)
        data['c17'].append(c17)

df = pd.DataFrame.from_dict(data)
df
问题原因

该文件本质是固定宽度格式文件,并非普通空白字符分隔的CSV。原代码使用\s+作为分隔符拆分时,会把第4列内部的空格也识别为列分隔符,导致拆分后的字段总数超过17,触发变量解包报错。同时' '.join(c4)的写法错误,拆分后的c4是单个字符串,执行join会将字符串按字符拆分后拼接,结果不符合预期。

解决方案

方案1:使用pandas内置read_fwf读取(推荐)

pandas的read_fwf专门用于读取固定宽度格式文件,无需手动逐行处理:

import pandas as pd

# 根据样例的列对齐情况手动指定每列宽度
col_widths = [10, 5, 17, 24, 26, 22, 3, 6, 12, 5, 5, 20, 9, 8, 11, 13]
# 读取无表头的固定宽度文件,自定义列名
df = pd.read_fwf('datasource.csv', widths=col_widths, header=None)
df.columns = [f'c{i+1}' for i in range(17)]

方案2:修正正则逐行匹配逻辑

如果要保留逐行处理的写法,改用正则分组捕获的方式提取字段:

import re
import pandas as pd

# 正则分组规则:前3列匹配非空白字符,第4列匹配任意字符(含内部空格),后13列匹配非空白字符
pattern = re.compile(r'^(\S+)\s+(\S+)\s+(\S+)\s+(.+?)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$')
data = {f'c{i+1}': [] for i in range(17)}

with open('datasource.csv', 'r', encoding='utf-8') as f:
    for line in f:
        line = line.rstrip('\n')
        match_res = pattern.match(line)
        if not match_res:
            continue
        groups = match_res.groups()
        for idx in range(17):
            # 第4列保留原始空格,其余列去除首尾多余空白
            val = groups[idx] if idx == 3 else groups[idx].strip()
            data[f'c{idx+1}'].append(val)

df = pd.DataFrame(data)

内容的提问来源于stack exchange,提问作者grinim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:24:07