如何让Pandas read_fwf读取无换行符的连续字节流固定宽文件?
解决Pandas read_fwf读取无换行固定宽度文件只读第一条的问题
我之前也碰到过类似的情况,确实read_fwf默认是按换行符来识别每条记录的边界的,你的文件是连续字节流没有换行,它自然读完第一条就以为到文件末尾了。这里有几个可行的解决方案:
方法一:计算总记录数后指定nrows
首先你需要明确每条记录的固定宽度(比如单条记录占100字节),然后先获取文件总字节数,用总字节数除以单条宽度得到总记录数,再把这个数值传给read_fwf的nrows参数,强制它读取所有记录:
import os import pandas as pd # 替换为你的单条记录固定宽度 record_width = 100 file_path = "your_target_file.dat" # 获取文件总字节数 file_size = os.path.getsize(file_path) # 计算总记录数(整除避免小数) total_records = file_size // record_width # 读取文件,widths按实际字段宽度拆分,比如多字段填[20,30,50] df = pd.read_fwf( file_path, widths=[record_width], nrows=total_records, header=None # 无表头时添加该参数 )
方法二:手动拆分字节流后转为DataFrame
如果文件体积过大,担心一次性计算总记录数占用内存,可以分块读取文件,按固定宽度拆分记录后再拼接成DataFrame:
import pandas as pd record_width = 100 # 每次读取1MB的字节块,可根据内存情况调整 chunk_size = 1024 * 1024 records = [] with open("your_target_file.dat", "rb") as f: while True: chunk = f.read(chunk_size) if not chunk: break # 拆分当前块为完整记录,过滤掉末尾不完整的字节 full_chunk_length = len(chunk) - (len(chunk) % record_width) full_records = chunk[:full_chunk_length] # 按固定宽度拆分记录 records.extend([full_records[i:i+record_width] for i in range(0, full_chunk_length, record_width)]) # 将剩余不完整字节放回文件指针,下次循环合并读取 remaining = chunk[full_chunk_length:] if remaining: f.seek(-len(remaining), 1) # 字节转字符串(根据文件实际编码调整,比如gbk、utf-8) str_records = [r.decode("utf-8") for r in records] # 用换行符拼接后再交给read_fwf处理 df = pd.read_fwf(pd.io.common.StringIO("\n".join(str_records)), widths=[20,30,50], header=None)
方法三:用Numpy直接读取二进制固定宽度文件
如果你的文件是纯数值类型的二进制固定宽度格式,用Numpy会更高效,完全绕开Pandas的行识别逻辑:
import numpy as np import pandas as pd # 定义字段类型和宽度,比如两个int32字段各占4字节 dtype = np.dtype([('field1', 'i4'), ('field2', 'i4')]) # 直接按二进制格式读取整个文件 arr = np.fromfile("your_target_file.dat", dtype=dtype) # 转为DataFrame df = pd.DataFrame(arr)
需要注意:如果是文本型固定宽度文件,要确保编码和字段宽度匹配(比如中文是多字节,不能按单字符宽度计算)。
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

