如何用for循环将IGC文本数据正确解析为pandas DataFrame列
IGC飞行数据解析代码返回None问题修复方案
问题背景
- 实现目标:批量解析存储飞行数据的IGC文件,提取全部有效飞行记录后导出为Excel列表。
- 初期测试代码:编写脚本读取IGC文件,遍历所有行筛选以
B开头的定位记录行并打印,代码如下:
with open('2022-07-04-XCT-VSH-16.igc','r') as flight: for line in flight: if line.startswith('B'): print(line)
- 测试运行成功,输出的B类定位记录格式示例如下:
B1644044003365N10517994WA019110191672 B1644054003365N10517994WA019110191792 B1644064003365N10517994WA019110191690 B1644074003366N10517993WA019110191717 B1644084003366N10517993WA019110191708 B1644094003365N10517993WA019110191775 B1644104003365N10517993WA019110191725 B1644114003364N10517993WA019110191872 B1644124003364N10517992WA019110191856 ....
上述B类记录就是需要解析的核心飞行数据。
原代码问题
后续编写解析逻辑时,预定义了包含timestamp、latitude、longitude、alt_pressure、alt-GPS列的空DataFrame,遍历B开头行时按固定字符位置切分字段逐行追加,原代码如下:
df = pd.DataFrame(columns=['timestamp','latitude','longitude','alt_pressure','alt-GPS']) def flightparser(): with open('2022-07-04-XCT-VSH-16.igc','r') as flight: for line in flight: if (line.startswith('B')): df2 = df.append({ 'timestamp' : [int(line[1:7])], 'latitude' : [str(line[7:15])], 'longitude' : [str(line[15:24])], 'alt-pressure' : [int(line[25:30])], 'alt-GPS' : [int(line[30:35])],},ignore_index=True) flightparser() print(df2)
运行后返回结果为None,无法得到预期的结构化数据表。
错误原因
- 变量作用域问题:
df2定义在函数内部循环中,函数无返回值,外部直接调用打印会触发空值错误。 - 列名不匹配:预定义列名为
alt_pressure,追加数据时写为alt-pressure,字段名不一致会导致数据错位。 - 追加逻辑错误:pandas的
append方法不会修改原DataFrame,而是返回新对象,循环中每次赋值只会保留最后一行的临时结果,且没有回写到全局DataFrame中。 - 无效嵌套:给每个字段值额外包裹列表,会导致单元格存储列表对象而非标量值。
- 性能缺陷:逐行追加DataFrame的写法效率极低,文件行数较多时运行速度会非常慢。
可行修复方案
推荐先把所有解析完成的记录存入普通列表,最后一次性转换为DataFrame,兼顾代码稳定性和运行效率,单文件解析代码如下:
import pandas as pd def parse_igc(file_path): records = [] with open(file_path, 'r', encoding='utf-8') as f: for line in f: line = line.strip() # 过滤长度不足的无效B记录 if line.startswith('B') and len(line) >= 35: # 按IGC固定格式切分字段 record = { 'timestamp': line[1:7], 'latitude': line[7:15], 'longitude': line[15:24], 'alt_pressure': int(line[25:30]), 'alt-GPS': int(line[30:35]) } records.append(record) # 一次性生成DataFrame return pd.DataFrame(records) if __name__ == '__main__': # 单文件解析测试 flight_df = parse_igc('2022-07-04-XCT-VSH-16.igc') print(flight_df.head()) # 导出为Excel flight_df.to_excel('flight_result.xlsx', index=False)
如果需要批量解析文件夹下所有IGC文件,可以增加目录遍历逻辑,示例如下:
import os def batch_parse(folder_path): all_flights = [] for filename in os.listdir(folder_path): if filename.lower().endswith('.igc'): single_df = parse_igc(os.path.join(folder_path, filename)) # 增加文件名字段区分不同飞行架次 single_df['flight_file'] = filename all_flights.append(single_df) # 合并所有数据 total_df = pd.concat(all_flights, ignore_index=True) total_df.to_excel('all_flights.xlsx', index=False) return total_df
拓展提示:如果需要把IGC里的度分格式经纬度转换为通用十进制度,只需要在切分字段后增加度分转十进制的计算逻辑即可。
内容的提问来源于stack exchange,提问作者Data_Sighentist
相关产品推荐
相关产品推荐

