Pandas按时间分组计算各高度层风速模值相邻差值方法
风场相邻高度层风速模值差计算方案
数据集说明
风场观测数据集包含以下字段:
timestamp:观测时间戳high:观测高度windSpeed:观测风速windDir:观测风向windU:风速U分量windV:风速V分量
数据样例如下:
timestamp high windSpeed windDir windU windV 04/05/2019 10:02 100 4.39 179.1 -0.14 8.53 150 2.44 164.5 -1.26 4.57 200 4.29 180.9 0.12 8.32 04/05/2019 10:03 100 4.39 179.1 -0.15 8.53 150 2.44 164.5 -1.26 4.57 200 4.29 180.9 0.12 8.32 04/05/2019 10:04 100 4.52 179.1 -0.16 8.79 150 2.15 162.8 -1.24 4 200 3.34 181.9 0.21 6.49 04/05/2019 10:05 100 4.52 179.1 -0.17 8.79 150 2.15 162.8 -1.24 4 200 3.34 181.9 0.21 6.49
需求说明
按时间戳对数据分组,对每个时间分组内的数据,计算更高高度层与更低高度层的风速模值差值,风速模值计算公式为:windMag = sqrt(windU² + windV²)
原有遍历代码仅能返回1个差值结果,无法得到所有相邻高度层的计算值,原有代码问题如下:
- 内层循环重复计算全组风速模值,存在冗余计算
- 直接使用全局行索引做遍历基准,索引不连续时会取错数据
- 计算得到的差值没有做持久化存储,循环结束后仅保留最后一次计算的结果
- 没有提前对组内高度做排序,高度乱序时会出现差值计算逻辑错误
实现代码
修正后的遍历写法
逻辑直观,适合需要自定义差值计算规则的场景:
import pandas as pd from math import sqrt # 先按时间、高度升序排序,保证同时间组内高度从低到高排列 grouped = df.sort_values(["timestamp", "high"]).groupby("timestamp", group_keys=False) result = [] for timestamp, group in grouped: # 单次计算当前组所有高度的风速模值 windMag = (group["windU"] ** 2 + group["windV"] ** 2).apply(sqrt) # 重置索引,避免全局索引干扰遍历 windMag = windMag.reset_index(drop=True) height_list = group["high"].reset_index(drop=True) # 遍历所有相邻高度对 for i in range(len(windMag) - 1): diff_val = windMag.iloc[i+1] - windMag.iloc[i] result.append({ "timestamp": timestamp, "lower_height": height_list.iloc[i], "upper_height": height_list.iloc[i+1], "windMag_diff": diff_val }) # 转换为DataFrame格式,方便后续分析 diff_df = pd.DataFrame(result)
高效向量化写法
基于pandas原生接口实现,无显式循环,计算速度远高于遍历写法,适合大数据量场景:
import pandas as pd import numpy as np # 按时间、高度升序排序 df_sorted = df.sort_values(["timestamp", "high"]).copy() # 计算所有点位的风速模值 df_sorted["windMag"] = np.sqrt(df_sorted["windU"] ** 2 + df_sorted["windV"] ** 2) # 按时间分组,计算相邻高度的风速模值差(高层减低层) df_sorted["windMag_diff"] = df_sorted.groupby("timestamp")["windMag"].diff() # 过滤掉每个时间组最低高度(无更低层,差值为NaN)的行 diff_result = df_sorted.dropna(subset=["windMag_diff"]).rename(columns={"high": "upper_height"}) # 补充对应下层高度字段 diff_result["lower_height"] = df_sorted.groupby("timestamp")["high"].shift(1).loc[diff_result.index] # 提取需要的列 diff_result = diff_result[["timestamp", "lower_height", "upper_height", "windMag_diff"]]
注意:无论使用哪种写法,必须提前对同时间组内的高度做升序排序,否则会出现高低层顺序颠倒,差值正负错误的问题。
内容的提问来源于stack exchange,提问作者Suci
相关产品推荐
相关产品推荐

