Python读取含多数据块的文件并生成指定三列输出的方法
问题与解决方案
问题描述
输入文件内容如下:
input_range 1.020000 ascii_format TRUE data 5000 0.000000e+000 2.902222e-001 1.000000e+000 2.902222e-001 2.000000e+000 2.905273e-001 3.000000e+000 2.902222e-001 4.000000e+000 2.911377e-001 5.000000e+000 2.908325e-001 input_range 1.020000 ascii_format TRUE data 5000 0.000000e+000 3.902222e-001 1.000000e+000 3.902222e-001 2.000000e+000 3.905273e-001 3.000000e+000 3.902222e-001 4.000000e+000 3.911377e-001 5.000000e+000 3.908325e-001
需求:生成包含三列的输出文件,第一列为第一个data标识后的第一列数据,第二列为第一个data标识后的第二列数据,第三列为第二个data标识后的第二列数据。询问仅用DataFrame能否实现,还是需要结合readlines方法。
解决方案
两种方法都可行:既可以结合readlines定位数据块后用DataFrame处理,也可以仅用pandas的功能完成。
方法1:结合readlines拆分数据块
先读取文件所有行,定位两个data行的位置,分别提取对应的数据块,再合并成目标结构:
import pandas as pd # 读取文件所有行 with open('input_file.txt', 'r') as f: lines = f.readlines() # 找到所有含'data'的行索引 data_positions = [idx for idx, line in enumerate(lines) if 'data' in line] # 提取第一个数据块:从第一个data行后到第二个data行前 df1 = pd.read_csv( pd.io.common.StringIO(''.join(lines[data_positions[0]+1 : data_positions[1]])), sep=r'\s+', header=None, names=['col1', 'col2'] ) # 提取第二个数据块:从第二个data行后到文件末尾 df2 = pd.read_csv( pd.io.common.StringIO(''.join(lines[data_positions[1]+1 :])), sep=r'\s+', header=None, names=['col1', 'col3'] ) # 按col1合并,得到目标三列 result = pd.merge(df1[['col1', 'col2']], df2[['col1', 'col3']], on='col1') # 保存结果 result.to_csv('output_file.txt', sep='\t', index=False)
方法2:仅用pandas功能实现
通过标记数据块、筛选有效数据行来完成,不需要手动读取所有行:
import pandas as pd # 读取整个文件,暂用默认列名 raw_df = pd.read_csv('input_file.txt', sep=r'\s+', header=None) # 标记哪些行是data块的起始行 raw_df['is_data_start'] = raw_df[0].str.contains('data', na=False) # 给每个数据块分配唯一标识 raw_df['block_id'] = raw_df['is_data_start'].cumsum() # 筛选出数据行(排除配置行,即第一列无法转为数字的行) data_rows = raw_df[pd.to_numeric(raw_df[0], errors='coerce').notna()] # 拆分两个数据块并重命名列 block1 = data_rows[data_rows['block_id'] == 1].reset_index(drop=True).rename(columns={0: 'col1', 1: 'col2'}) block2 = data_rows[data_rows['block_id'] == 2].reset_index(drop=True).rename(columns={0: 'col1', 1: 'col3'}) # 拼接得到目标三列 result = pd.concat([block1[['col1', 'col2']], block2['col3']], axis=1) # 保存输出 result.to_csv('output_file.txt', sep='\t', index=False)
总结
- 仅用DataFrame完全可以实现,通过数据块标记和筛选就能完成;
- 结合
readlines的方法更直观,适合对文件结构非常明确的场景,定位数据块更直接。
内容的提问来源于stack exchange,提问作者kata248
相关产品推荐
相关产品推荐

