根据报错信息 concurrent.futures.process.BrokenProcessPool,这个错误通常表示在任务执行过程中,有一个子进程异常终止。常见原因包括:
内存问题:处理的数据量太大,导致内存不足,从而使子进程被操作系统强制终止。
子进程错误:子进程在执行过程中遇到错误,导致崩溃。
数据序列化问题:传递给子进程的数据量太大或包含无法序列化的对象。
为了解决这个问题,我们可以进行以下几步操作:
1. 增加错误处理
在 compute_lrmes_for_date 函数中增加错误处理,并打印错误信息以便调试。
2. 确保数据索引为日期时间类型
确保传递给子进程的数据索引为 DatetimeIndex 类型,以避免数据格式问题。
3. 打印调试信息
添加调试信息,帮助定位问题所在。
修改后代码:
import numpy as np
import pandas as pd
from concurrent.futures import ProcessPoolExecutor
import traceback
from frds.measures import LRMES
def compute_lrmes_for_date(args):
try:
date, data = args
if date.year < 2007:
return None
sub_data = data.loc[:date]
lrmes = LRMES(sub_data["Rccb"], sub_data["Rhs300"]).estimate(h=22 * 6, C=-0.4)
print((date, lrmes))
return (date, lrmes)
except Exception as e:
print(f"Error processing date {date}: {e}")
traceback.print_exc()
return None
if __name__ == "__main__":
# 加载数据
data = pd.read_excel(r'C:\Users\Administrator\Desktop\test2.xlsx')
# 确保索引为日期时间类型
if not isinstance(data.index, pd.DatetimeIndex):
data.index = pd.to_datetime(data.index)
with ProcessPoolExecutor() as executor:
lrmes_values = list(
executor.map(
compute_lrmes_for_date,
[(d, data) for d in data.index.unique()],
)
)
# 过滤掉None值
lrmes_values = [x for x in lrmes_values if x is not None]
lrmes_df = pd.DataFrame(lrmes_values, columns=["Date", "LRMES"]).set_index("Date")
# 合并数据
data = pd.merge_asof(data, lrmes_df, left_index=True, right_index=True, direction="backward")
# 保存更新后的数据
data.to_excel(r'C:\Users\Administrator\Desktop\output.xlsx')
进一步的调试步骤
运行脚本:执行修改后的脚本,查看输出的调试信息和错误日志。
监控资源使用:在执行脚本时,监控系统的内存和CPU使用情况,确保资源没有被耗尽。
分块处理数据:如果数据量很大,可以尝试分块处理,减少每个子进程处理的数据量。例如,将数据按年份或月份分块处理。
通过上述步骤,我们可以逐步定位和解决子进程异常终止的问题