如何优化Python解析固定格式文本表格为pd.DataFrame的实现
针对你解析固定宽度气象站文本表格的需求,推荐用Pandas原生的read_fwf()方法,这是最可靠且简洁的方案,完美解决你之前遇到的两个痛点:带空格的站名被拆分、硬编码列位置不可靠。
核心实现代码
import pandas as pd # 自动推断列宽读取固定宽度文件 df = pd.read_fwf('isd-history.txt', colspecs='infer', header=0) # 可选:清洗列名,去除首尾多余空格 df.columns = [col.strip() for col in df.columns] # 查看处理后的结果 print(df.sample(5))
为什么这是最优解?
- 自动适配列宽:
colspecs='infer'会让Pandas自动分析表头和数据行的对齐关系,精准识别每列的宽度,完全不用手动硬编码位置,避免了格式变动导致的失效问题。 - 完整保留含空格字段:固定宽度解析是按位置截取内容,像
JAN MAYEN(NOR-NAVY)这类带空格的站名会被完整读取,不会被正则拆分打散。 - 一步生成DataFrame:直接输出可用于分析的DataFrame,省去了手动逐个提取字段再拼接的繁琐步骤。
针对你现有方案的补充优化
1. 正则拆分的改进版
如果一定要用正则处理,可以用至少两个空格作为分隔符(数据列之间是多空格分隔,而字段内部是单空格),这样能避免拆分带空格的字段:
import re import pandas as pd with open('isd-history.txt') as f: # 过滤空行并去除每行首尾空格 lines = [line.strip() for line in f if line.strip()] # 拆分表头和数据 headers = re.split(r'\s{2,}', lines[0]) data_rows = [re.split(r'\s{2,}', line) for line in lines[1:]] # 生成DataFrame df = pd.DataFrame(data_rows, columns=headers)
不过这种方法依赖数据列之间是多空格分隔,如果遇到列之间无空格仅靠位置对齐的固定宽度文件,就会失效,不如read_fwf通用。
2. 硬编码位置的优化
如果因为特殊需求必须手动指定列范围,也可以用read_fwf的colspecs参数替代手动切片,代码更清晰易维护:
import pandas as pd # 根据你的数据格式手动定义各列的起止索引(左闭右开) col_ranges = [ (0, 6), (7, 12), (13, 43), (43, 45), (46, 50), (51, 55), (57, 64), (65, 73), (74, 81), (82, 90), (91, 100) ] # 指定列名读取文件 df = pd.read_fwf( 'isd-history.txt', colspecs=col_ranges, header=None, skiprows=1, names=['USAF', 'WBAN', 'STATION NAME', 'CTRY', 'ST', 'CALL', 'LAT', 'LON', 'ELEV(M)', 'BEGIN', 'END'] )
内容的提问来源于stack exchange,提问作者topcat
相关产品推荐
相关产品推荐

