Pandas DataFrame循环实现多坐标区间粒子数据批量计算
多坐标区间粒子统计批量实现方案
核心思路是将单区间的重复计算逻辑封装为可复用函数,将所有待计算的坐标区间整理为参数配置列表,通过遍历配置批量完成计算,完全避免手动编写重复代码。
1. 封装单区间统计函数
将原有单区间的筛选、分组聚合、全局指标计算逻辑抽离为通用函数,入参为原始数据集、x/y区间上下限、可选区间编号,输出为符合要求格式的统计结果表,同时补全了区间无粒子时的除零异常处理:
import pandas as pd import numpy as np def calc_bin_stats(df: pd.DataFrame, x_min: float, x_max: float, y_min: float, y_max: float, bin_id: str = None) -> pd.DataFrame: # 筛选落在当前坐标区间内的粒子 bin_particles = df.loc[ (df['x'] > x_min) & (df['x'] < x_max) & (df['y'] > y_min) & (df['y'] < y_max) ] # 按TIMESTEP分组聚合基础指标 timestep_agg = bin_particles.groupby("TIMESTEP", as_index=False).agg( nparticles = ("id", "count"), v_x=("vx", "sum"), v_y=("vy", "sum"), radius = ("radius", "sum"), area_sum = ("Area", "sum") ) # 计算区间全局平均速度、phi指标 total_particles = timestep_agg["nparticles"].sum() if total_particles == 0: vx_a1, vy_a1 = 0.0, 0.0 else: vx_a1 = timestep_agg["v_x"].sum() / total_particles vy_a1 = timestep_agg["v_y"].sum() / total_particles phi_1 = timestep_agg["area_sum"].sum() / 1001 # 将全局指标匹配到每个TIMESTEP行,对齐目标输出结构 timestep_agg[["vx_a1", "vy_a1", "phi_1"]] = [vx_a1, vy_a1, phi_1] # 新增区间标识列,方便后续多区间结果合并区分 if bin_id: timestep_agg["bin_id"] = bin_id return timestep_agg
2. 生成区间配置列表
把所有需要计算的50+组坐标区间整理为参数列表,规则网格区间可以直接通过numpy自动生成,无需手动逐行填写;自定义不规则区间直接追加到列表即可:
bin_configs = [] # 示例:自动生成原有代码参数对应的规则网格区间 bindistance = 0.25 x_centers = np.arange(-4.0, 4.0, bindistance) y_centers = np.arange(-0.5, 0.6, 1.0) # 对应原有y区间[-0.5, 0.5] bin_idx = 1 for xc in x_centers: for yc in y_centers: bin_configs.append({ "x_min": xc - bindistance*2, "x_max": xc + bindistance*2, "y_min": yc - 0.5, "y_max": yc + 0.5, "bin_id": f"bin_{bin_idx}" }) bin_idx += 1 # 自定义区间直接追加即可,例如: # bin_configs.append({"x_min":1.0, "x_max":3.0, "y_min":0, "y_max":2.0, "bin_id":"custom_1"})
3. 批量遍历计算所有区间结果
遍历配置列表调用封装好的统计函数,收集所有区间的结果,可按需合并为总表或者按区间编号存储为字典单独调用:
all_results = [] result_map = {} for cfg in bin_configs: bin_res = calc_bin_stats( df, x_min=cfg["x_min"], x_max=cfg["x_max"], y_min=cfg["y_min"], y_max=cfg["y_max"], bin_id=cfg["bin_id"] ) all_results.append(bin_res) result_map[cfg["bin_id"]] = bin_res # 合并所有区间结果为一张总表 final_output = pd.concat(all_results, ignore_index=True)
效率优化提示
- 如果数据集量级超过百万行,循环筛选的效率偏低,可以先用
pd.cut()给所有粒子数据提前打上x、y所属区间的标签,再按[x_bin, y_bin, TIMESTEP]一次性分组聚合,计算速度会提升数倍 - 注意保持区间开闭规则和原有单区间代码一致,避免边界粒子漏算、重复统计
- 函数内置了空区间的除零保护,遇到无粒子的区间不会抛出运行错误
内容的提问来源于stack exchange,提问作者Sameer S
相关产品推荐
相关产品推荐

