使用tabulate模块将DataFrame写入固定宽度文件的实现问题
Pandas自定义to_fwf支持colspecs参数的解决方案
原来基于tabulate的实现默认根据内容自动计算列宽,没有开放自定义列宽规格的入口,无法输出符合指定宽度要求的固定宽度文件,可通过以下两种方案解决:
方案1:改造现有tabulate实现,新增colspecs参数支持
可直接覆盖原有的自定义to_fwf函数,新增colspecs参数处理逻辑,兼容tabulate原有自动列宽能力的同时,支持自定义固定宽度:
from tabulate import tabulate import pandas as pd def to_fwf(df, fname, colspecs=None, encoding="utf-8"): # 未指定colspecs时沿用原有tabulate自动列宽逻辑 if colspecs is None: content = tabulate(df.values.tolist(), list(df.columns), tablefmt="plain") else: headers = list(df.columns) formatted_lines = [] # 解析colspecs,兼容两种格式:仅宽度列表 / 和read_fwf对齐的(起始位置, 结束位置)列表 col_widths = [] for spec in colspecs: if isinstance(spec, (tuple, list)): col_widths.append(spec[1] - spec[0]) else: col_widths.append(spec) # 格式化表头 header_line = "".join([f"{headers[i]:<{w}}"[:w] for i, w in enumerate(col_widths)]) formatted_lines.append(header_line) # 格式化数据行 for _, row in df.iterrows(): data_line = "".join([f"{str(row.iloc[i]):<{w}}"[:w] for i, w in enumerate(col_widths)]) formatted_lines.append(data_line) content = "\n".join(formatted_lines) # 用with语句安全写入文件 with open(fname, "w", encoding=encoding) as f: f.write(content) # 绑定到DataFrame类 pd.DataFrame.to_fwf = to_fwf
调用示例:
# 指定三列宽度分别为12、20、8 df.to_fwf("test.fwf", colspecs=[12,20,8]) # 兼容read_fwf的起止位置格式 df.to_fwf("test.fwf", colspecs=[(0,12), (12,32), (32,40)])
方案2:无第三方依赖的原生实现
如果不想引入tabulate依赖,可直接删除tabulate相关逻辑,完全用Python原生字符串格式化实现,逻辑更轻量化可控。
补充说明:
- 若需要数值列右对齐,可将格式化字符
<替换为> - 若需要列之间保留固定分隔空格,可在拼接每行时额外插入对应空格即可
内容的提问来源于stack exchange,提问作者Valentyn
相关产品推荐
相关产品推荐

