Python如何计算非数值字符串类型风向数据的平均值
风向平均值计算解决方案
核心原理
风向属于环形角度值,直接做算术平均会出现逻辑错误(比如0°北风和359°北风的算术平均是179.5°南风,和实际情况完全不符)。正确的计算逻辑是先把风向分解为东西(u)、南北(v)两个矢量分量,对分量求平均后再转换回角度,最后映射为风向字符串,全程可借助numpy的向量运算能力实现,无需循环遍历,处理效率极高。
实现步骤
- 步骤1:建立16方位风向和角度的映射关系(如果你的数据是8方位,调整映射字典即可)
- 步骤2:将数据中的风向字符串转换为对应角度
- 步骤3:利用numpy向量运算将角度分解为u、v分量,计算分量均值
- 步骤4:将平均分量转换为0~360°范围内的平均角度,再映射回风向字符串
完整代码示例
import pandas as pd import numpy as np # 16方位风向对应的角度(以北为0°,顺时针递增) DIR_TO_DEG = { 'N': 0, 'NNE': 22.5, 'NE': 45, 'ENE': 67.5, 'E': 90, 'ESE': 112.5, 'SE': 135, 'SSE': 157.5, 'S': 180, 'SSW': 202.5, 'SW': 225, 'WSW': 247.5, 'W': 270, 'WNW': 292.5, 'NW': 315, 'NNW': 337.5 } # 反向映射:角度转风向 DEG_TO_DIR = {v: k for k, v in DIR_TO_DEG.items()} def calc_mean_wind_dir(wind_dir_series): # 风向字符串转角度 deg_series = wind_dir_series.map(DIR_TO_DEG) # 角度转弧度,分解为u、v分量(全向量运算,无循环) rad = np.radians(deg_series) u = np.sin(rad) v = np.cos(rad) # 计算分量均值 u_mean = u.mean() v_mean = v.mean() # 处理无风场景:各方向风矢量完全抵消,风向无意义 if np.isclose(u_mean, 0) and np.isclose(v_mean, 0): return np.nan, np.nan # 平均分量转角度,调整到0~360范围 mean_rad = np.arctan2(u_mean, v_mean) mean_deg = np.degrees(mean_rad) % 360 # 匹配最近的风向字符串 closest_deg = min(DEG_TO_DIR.keys(), key=lambda x: abs(x - mean_deg)) return DEG_TO_DIR[closest_deg], mean_deg # 测试用例,对应你给出的示例数据 df = pd.DataFrame({ 'time': ['2010-08-27 00:00:00', '2010-08-27 00:15:00', '2010-08-27 00:30:00', '2010-08-27 00:45:00', '2010-08-27 01:00:00'], 'wind_dir': ['SW', 'SSW', 'SSW', 'SSE', 'NNE'] }) # 调用函数计算平均风向 mean_dir_str, mean_dir_deg = calc_mean_wind_dir(df['wind_dir']) print(f"平均风向角度:{mean_dir_deg:.2f},对应风向:{mean_dir_str}")
扩展说明
如果需要按时间窗口(比如每小时、每天)计算平均风向,搭配pandas的resample方法即可,整个运算过程都是向量化执行,百万行级别的时序数据也可以在秒级完成计算。
内容的提问来源于stack exchange,提问作者Martín
相关产品推荐
相关产品推荐

