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

如何使用Pandas读取无分隔符、各列宽度不同的固定宽度文本文件

pandas读取无分隔符固定宽度文本文件配置方法

问题场景

需要使用pandas读取无分隔符的定宽纯文本文件,各列宽度不统一,示例数据如下:

59967Y98Doe John            6211100004545SO20140314-  00024278
N0546664SCHMIDT-PETER       7441100008300AW20140314-  00023643
G4894jmhTAKLONSKY-JUERGEN   4211100005000TB20140315   00023882
34875738PODESBERG-SCHUMPERTS6211100003671SO20140315   00024622

各列宽度、数据类型规则:

  • 1-8位:字符串类型
  • 9-28位:字符串类型
  • 29-31位:数值类型
  • 32-34位:数值类型
  • 35-41位:数值类型
  • 42-43位:字符串类型
  • 44-51位:yyyyMMdd格式的日期
  • 第52位:负号或空格
  • 剩余部分:无小数点的货币金额(最后两位为小数位,例如- 00024278对应-242.78 €)

已知pandas的pd.read_fwf方法支持widths参数,但目前仅能实现单列读取,示例代码如下:

pd.read_fwf(StringIO(txt), widths=[8], header="Peronal Nr.")

需要明确参数配置方法,实现这类定宽文件的正确读取。

实现方法

核心是按列的顺序把所有列的宽度值按顺序传入widths参数,再搭配类型转换参数处理特殊格式字段,避免自动类型转换导致的数据错误:

  1. 先逐段计算每列的固定宽度,按照从左到右的顺序,列宽依次为:8、20、3、3、7、2、8、1,最后一段金额部分可设置为足够大的数值,方法会自动读取到行尾
  2. 读取阶段先将所有字段按字符串类型读入,避免前导零丢失、符号位被自动过滤的问题
  3. 读取完成后逐列做类型转换,单独处理日期、带符号货币这类特殊格式字段

完整可运行代码:

import pandas as pd
from io import StringIO

txt = """59967Y98Doe John            6211100004545SO20140314-  00024278
N0546664SCHMIDT-PETER       7441100008300AW20140314-  00023643
G4894jmhTAKLONSKY-JUERGEN   4211100005000TB20140315   00023882
34875738PODESBERG-SCHUMPERTS6211100003671SO20140315   00024622
"""

# 定义列名与对应列宽
col_names = [
    "personal_nr", "name", "num_col1", "num_col2", "num_col3",
    "type_code", "trans_date", "amount_sign", "amount_val"
]
col_widths = [8, 20, 3, 3, 7, 2, 8, 1, 10]

# 全字段按字符串读取,关闭默认空值转换
df = pd.read_fwf(
    StringIO(txt),
    widths=col_widths,
    header=None,
    names=col_names,
    dtype=str,
    keep_default_na=False
)

# 逐列做类型转换
# 普通数值列转整数
for col in ["num_col1", "num_col2", "num_col3"]:
    df[col] = pd.to_numeric(df[col])
# 日期列转datetime类型
df["trans_date"] = pd.to_datetime(df["trans_date"], format="%Y%m%d")
# 货币金额处理:拼接符号,除以100得到两位小数的实际金额
df["amount_eur"] = df.apply(
    lambda row: -int(row["amount_val"].strip())/100 if row["amount_sign"] == "-" else int(row["amount_val"].strip())/100,
    axis=1
)
# 清理临时字段
df = df.drop(columns=["amount_sign", "amount_val"])

注意:如果文件末尾金额列长度不固定,只要把最后一个宽度值设置为大于等于该列最大可能长度的数值即可,不需要精确匹配,read_fwf会自动识别行尾不会多读内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:39:19