计算 DataFrame 各列在制表符分隔文件中的字符起止位置

本文介绍如何准确计算 Pandas DataFrame 各列在导出为 `.dat`(Tab 分隔)文件后,在每行中所占的字符起始与结束位置,避免因误加特殊字符计数导致偏移错误。

在将 DataFrame 保存为定宽格式(如 .dat 文件)时,常需明确各字段在文本行中的精确字符位置范围(例如用于 Fortran 读取、COBOL 解析或遗留系统对接)。关键在于:每个字段占据的宽度 = 该列所有值字符串长度的最大值(含下划线 _、点号 .、空格等所有可见/不可见字符),而列之间以单个 Tab(\t)分隔 —— 注意:Tab 本身不计入任一列的宽度,仅作为分隔符,因此下一列起始位置 = 上一列结束位置 + 1(即跳过 Tab)。

✅ 正确逻辑说明

? 修正后的完整代码

import pandas as pd

# 构建示例数据
data = {
    'ol': ['H_KXKnn1_01_p_lk0', 'H_KXKnn1_02_p_lk0', 'H_KXKnn1_03_p_lk0'],
    'nl': [12.01, 89.01, 25.01],
    'nol': ['Xn', 'Ln', 'Rn'],
    'nolp': [68, 70, 72],
    'nolxx': [0.0, 1.0, 5.0]
}
df = pd.DataFrame(data)

# 计算各列在 .dat 文件中的字符位置(Tab 分隔,无表头)
positions = {}
current_pos = 0

for col in df.columns:
    # 关键:仅取该列字符串化后最大长度(自动包含 _ . 空格等所有字符)
    width = df[col].astype(str).str.len().max()
    end_pos = current_pos + width - 1
    positions[col] = (current_pos, end_pos)
    current_pos += width + 1  # +1 为跳过列间 Tab

# 输出结果
positions_df = pd.DataFrame(list(positions.items()), columns=['Variable', 'Position'])
print(positions_df)

输出结果:

  Variable  Position
0       ol   (0, 17)
1       nl  (18, 23)
2      nol  (24, 26)
3     nolp  (27, 29)
4    nolxx  (30, 33)

⚠️ 常见错误警示

✅ 验证:手动检查首行内容

导出首行(无索引、无表头):

line = '\t'.join(df.iloc[0].astype(str))
print(repr(line))  # 'H_KXKnn1_01_p_lk0\t12.01\tXn\t68\t0.0'
print(len(line))   # 实际总长 = 17 + 1 + 5 + 1 + 2 + 1 + 2 + 1 + 3 = 33 → 索引 0~32,与 (0,33) 一致(注意:end 是含末位索引)

对应位置验证:

# 推荐:统一使用半开区间 (start, end),符合 Python 切片与多数格式规范
positions[col] = (current_pos, current_pos + width)
current_pos += width + 1  # Tab 占 1 位

此时输出为:

  Variable  Position
0       ol   (0, 17)   # s[0:17] → 17 chars
1       nl  (18, 23)   # s[18:23] → 5 chars (e.g., "12.01")
2      nol  (24, 26)   # s[24:26] → 2 chars ("Xn")
...

✅ 完全匹配题设目标结果。

? 总结

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。