无表头不规则多观测事件CSV读取与能量积分计算方案咨询
非规整观测事件CSV能量积分实现方案
实现思路
- 逐行流式读取文件:无需一次性加载全量内容,适配非固定长度的事件结构,同时避免内存溢出
- 事件块分割逻辑:
- 每次读取的第一行判定为事件头行,解析出16、17号仪器的探测标记,统计当前事件包含的仪器数据段数量
- 对每个仪器数据段,先读取数据点总数n,再连续读取n行作为该段的实测数据
- 所有关联数据段读取完成后,当前事件处理完毕,直接开始下一个事件的读取
- 能量积分计算:光变曲线积分优先用梯形法,对每个仪器的时间戳-能量序列按时间排序后做积分,多仪器探测的事件把各仪器积分结果相加得到单事件总能量
- 结果存储:用列表存储所有事件的总能量及关联属性,最后可按需输出为控制台打印或结果文件
Python代码框架
import csv import numpy as np # 若未安装scipy,可自行实现梯形积分逻辑替换下方trapezoid调用 from scipy.integrate import trapezoid # 存储所有事件的总能量结果 event_energies = [] with open('替换为你的CSV文件路径.csv', 'r', encoding='utf-8') as f: reader = csv.reader(f) while True: try: # 读取事件头行 header_row = next(reader) event_date, flag16, flag17, confidence = header_row flag16 = int(flag16) flag17 = int(flag17) current_event_total = 0.0 # 遍历所有探测到当前事件的仪器数据段 for valid_flag in [f for f in [flag16, flag17] if f != 0]: # 读取当前仪器的数据点总数 point_count = int(next(reader)[0]) timestamps = [] energies = [] # 读取对应数量的实测数据 for _ in range(point_count): ts, lat, lon, e = next(reader) timestamps.append(float(ts)) energies.append(float(e)) # 按时间戳排序避免数据乱序 sorted_pairs = sorted(zip(timestamps, energies), key=lambda x: x[0]) sorted_ts = [p[0] for p in sorted_pairs] sorted_e = [p[1] for p in sorted_pairs] # 积分结果累加到当前事件总能量 current_event_total += trapezoid(sorted_e, sorted_ts) # 存储当前事件结果 event_energies.append({ "event_date": event_date, "total_energy": current_event_total, "confidence": confidence }) except StopIteration: # 文件读取完成退出循环 break # 控制台打印结果 for idx, res in enumerate(event_energies, 1): print(f"事件{idx} | 日期:{res['event_date']} | 总能量:{res['total_energy']} | 置信度:{res['confidence']}") # 可选:导出结果为CSV with open('事件总能量结果.csv', 'w', encoding='utf-8', newline='') as f: writer = csv.DictWriter(f, fieldnames=["事件序号", "事件日期", "总能量", "探测置信度"]) writer.writeheader() for idx, res in enumerate(event_energies, 1): writer.writerow({ "事件序号": idx, "事件日期": res["event_date"], "总能量": res["total_energy"], "探测置信度": res["confidence"] })
注意事项
- 若CSV行存在空值、格式异常,可在数据解析逻辑外层加
try-except捕获异常,跳过异常事件或打印错误行号方便排查 - 若UTC时间戳为字符串格式,需先转成时间戳数值再做积分计算
- 无scipy依赖时,梯形积分可自行实现:遍历相邻时间点,累加
(t2-t1)*(e1+e2)/2即可得到单段积分结果
内容的提问来源于stack exchange,提问作者kasiaw
相关产品推荐
相关产品推荐

