如何基于风速风向区间匹配pandas数据表中的对应元素?
匹配气象数据到区间化二维表的方法
问题背景
我有一组按风速、风向区间划分的二维数据表,同时有一组包含风速、风向的气象观测数据,需要将每个(风速、风向)对匹配到二维表中对应的单元格数值。
1. 区间化二维数据表代码
import numpy as np import pandas as pd # 风速和风向的区间边界 speed_bins = np.array([0.0, 0.5, 1.0, 2.0, 5.0, 10.0, 100.0]) dir_bins = np.linspace(0, 360, 9) # 生成0–0.5之间的随机LPF值,构建区间对应二维表 data = np.random.rand(len(dir_bins)-1, len(speed_bins)-1)*0.5 dataTable = pd.DataFrame(data, index=dir_bins[1:], columns=speed_bins[1:])
2. 气象观测数据代码
import numpy as np import pandas as pd # 假设所有数组长度相同 speeds = np.array([...]) directions = np.array([...]) X = np.array([...]) metData = pd.DataFrame({'speeds': speeds, 'directions': directions, 'X': X})
需求说明
对每个(speed, direction)对:
- 找到该风速所属区间对应的
dataTable列 - 找到该风向所属区间对应的
dataTable行 - 返回对应单元格的数值
示例:当speed=0.75、direction=350时,需取dataTable.iat[7,1]的值。因为0.75落在[0.5,1.0]区间(对应列索引1),350落在[315,360]区间(对应行索引7)。
高效实现方案
方法1:用numpy.digitize批量匹配区间索引
# 为气象数据的风速、风向匹配区间索引 # digitize返回bins的索引,减1后对应dataTable的行列(dataTable索引为区间右边界) speed_indices = np.digitize(metData['speeds'], speed_bins) - 1 # 处理风向360度的特殊情况:digitize会把360分到最后一个区间,需修正为dataTable的最后一行索引 dir_indices = np.digitize(metData['directions'], dir_bins) - 1 dir_indices[dir_indices == len(dir_bins)-1] = len(dir_bins)-2 # 批量提取对应值 metData['matched_value'] = dataTable.to_numpy()[dir_indices, speed_indices]
方法2:用pandas.cut结合lookup(直观易读)
# 为风速、风向创建对应区间的标签(即dataTable的列名和索引) metData['speed_bin'] = pd.cut(metData['speeds'], bins=speed_bins, labels=speed_bins[1:], include_lowest=True) metData['dir_bin'] = pd.cut(metData['directions'], bins=dir_bins, labels=dir_bins[1:], include_lowest=True) # 批量匹配对应单元格的值 metData['matched_value'] = dataTable.lookup(metData['dir_bin'], metData['speed_bin'])
注意事项
numpy.digitize默认采用左开右闭区间规则,与dataTable的区间定义(用右边界作为标签)完全匹配;若需左闭右开,需设置right=True并调整索引逻辑。- 风向360度需单独处理:因为
dir_bins的最后一个值是360,digitize会将其分到超出dataTable行范围的索引,需手动修正为最后一行的索引。 - 两种方法均为批量处理,效率远高于循环遍历单条数据。
内容的提问来源于stack exchange,提问作者jlconlin
相关产品推荐
相关产品推荐

