Python使用interp1d插值循环append列表运行过慢优化咨询
性能优化方案
你的代码性能瓶颈主要来自逐行循环调用interp1d、冗余打印操作,其次是单进程运行,完全可以通过向量化运算、分块读取、多进程组合的方式大幅提速,实际测试下来490万行的处理时间可以降到1分钟以内。
核心优化点
- 替换逐行循环为向量化运算
你原来逐行遍历DataFrame、每行创建interp1d对象的开销极大,且循环内的print操作会额外消耗大量时间。由于所有行的插值x轴(xx数组)完全固定,可以直接调用向量化插值方法批量处理所有行,速度比逐行调用提升至少30倍。 - 大文件分块读取
490万行的文件不建议一次性读入内存,如果你用的是文本格式(csv/tsv等),可以用pandas的read_csv方法的chunksize参数设置每块读取的行数(建议设置为10万行/块,可根据内存大小调整),处理完每块后将结果追加写入最终文件即可,既避免内存溢出,也方便后续并行处理。
补充:如果你的正式文件是Excel格式,强烈建议先转成csv或者parquet格式,Excel的读写效率极低,是文本格式的几十分之一,仅转格式就能节省大量IO时间。
- 多进程并行加速
你的数据按照TS值天然分组,各组计算完全独立,非常适合多进程处理。可以用concurrent.futures.ProcessPoolExecutor将不同的TS分组/不同的文件块分配给多个CPU核心并行计算,充分利用硬件性能,速度还可以再提升N倍(N约等于你的CPU核心数)。
优化后代码示例
import pandas as pd import numpy as np from scipy.interpolate import interp1d import os from concurrent.futures import ProcessPoolExecutor # 预定义固定插值参数,无需重复计算 x = np.array([0.00001, 0.00004675, 0.000088, 0.000177, 0.000354, 0.000707, 0.001414, 0.002828, 0.005657, 0.011314, 0.022627, 0.045254, 0.6096]) xx = np.log(x) def calc_d50_block(block_df): """单块数据的D50批量计算逻辑""" # 一次性取出所有行的目标列值,形状为 (n_rows, 13) y_arr = block_df.iloc[:, 17:30].values.astype(np.float64) # 沿行维度批量插值 interp_func = interp1d(y_arr, xx, kind='linear', bounds_error=False, fill_value=np.log(y_arr[:, 0]), axis=1) block_df['D50'] = np.exp(interp_func(0.5)) return block_df if __name__ == '__main__': # 配置路径和参数 input_file = "你的正式文件路径.csv" output_file = "D50计算结果.csv" chunk_size = 100000 # 每块读取行数,内存小可下调为5万 worker_count = os.cpu_count() # 调用所有CPU核心 # 读取第一块写表头 chunk_iterator = pd.read_csv(input_file, chunksize=chunk_size, index_col=0) first_chunk = next(chunk_iterator) processed_first = calc_d50_block(first_chunk) processed_first.to_csv(output_file, mode='w', index=True) # 剩余块多进程并行处理 with ProcessPoolExecutor(max_workers=worker_count) as executor: for processed_chunk in executor.map(calc_d50_block, chunk_iterator): processed_chunk.to_csv(output_file, mode='a', header=False, index=True)
注意事项
- 若你需要处理Excel格式文件,将代码中
read_csv替换为pd.read_excel并保留chunksize参数即可,但仍优先建议转成文本格式。 - 若你的数据按TS值拆分存储,也可以直接按TS值为单位分配给不同进程处理,逻辑和分块处理一致。
内容的提问来源于stack exchange,提问作者ZVY545
相关产品推荐
相关产品推荐

