如何在Pandas中匹配数值所在区间并获取对应列值完成计算?
实现区间匹配并求和的几种实用方法
我来帮你搞定这个需求——判断数值落在指定区间,取对应sample值求和。下面是几种不同场景下的解决方案,你可以根据自己的数据量和需求选择:
方法1:用pd.cut()快速划分区间(适合单个/少量数值)
这个方法逻辑很直白,先把range列的数值作为区间分界点,再把x放到对应的区间里,直接映射sample值就行。
步骤&代码:
import pandas as pd # 先初始化你的映射DataFrame map_dict = { 'range' : [50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 40000, 80000, 120000], 'sample' : [1000, 1000, 1000, 1000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000] } df_map = pd.DataFrame.from_dict(map_dict) # 定义区间的分界点,要加上最左和最右的边界(处理x<=50或者x>120000的情况) bins = [-float('inf')] + df_map['range'].tolist() + [float('inf')] # 给每个区间对应上sample值,最后一个区间(x>120000)用最后一个sample值 labels = df_map['sample'].tolist() + [df_map['sample'].iloc[-1]] # 测试你的例子:x=4000 x = 4000 # 把x分到对应的区间,拿到sample值 sample_val = pd.cut([x], bins=bins, labels=labels, include_lowest=True)[0] # 求和 result = x + sample_val print(result) # 输出6000,完全符合你的要求
细节说明:
include_lowest=True是为了让第一个区间包含x<=50的情况- 如果要批量处理多个x,直接把x放到一个Series里传给
pd.cut()就行,它会批量处理
方法2:用pd.merge_asof()高效批量匹配(适合大数据量)
如果你要处理很多个x值(比如一整个DataFrame的数值),用merge_asof效率会高很多,它专门用来做这种区间型的匹配。
步骤&代码:
import pandas as pd # 初始化映射DataFrame map_dict = { 'range' : [50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 40000, 80000, 120000], 'sample' : [1000, 1000, 1000, 1000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000] } df_map = pd.DataFrame.from_dict(map_dict) # 假设我们有一批x要处理 df_x = pd.DataFrame({'x': [300, 4000, 150000]}) # merge_asof要求两边的DataFrame都按匹配键排序,所以先排序 df_x_sorted = df_x.sort_values('x') df_map_sorted = df_map.sort_values('range') # 给映射表加一列前一个range值,这样我们就能明确区间是(prev_range, range] df_map_sorted['prev_range'] = df_map_sorted['range'].shift(1).fillna(-float('inf')) # 用merge_asof找到每个x对应的区间行 merged = pd.merge_asof(df_x_sorted, df_map_sorted, left_on='x', right_on='prev_range', direction='forward') # 处理x大于最大range的情况,补上最后一个sample值 merged['sample'] = merged['sample'].fillna(df_map_sorted['sample'].iloc[-1]) # 计算求和结果 merged['result'] = merged['x'] + merged['sample'] print(merged)
输出结果:
x range sample prev_range result 0 300 500.0 1000 200.0 1300 1 4000 5000.0 2000 2000.0 6000 2 150000 NaN 2000 NaN 152000
方法3:自定义函数+apply(逻辑直观,适合小数据量)
如果数据量不大,你也可以写个自定义函数,手动找区间,逻辑一眼就能看明白。
步骤&代码:
import pandas as pd map_dict = { 'range' : [50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 40000, 80000, 120000], 'sample' : [1000, 1000, 1000, 1000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000] } df_map = pd.DataFrame.from_dict(map_dict) def calculate_sum(x): # 找到第一个比x大的range的索引 first_larger_idx = df_map[df_map['range'] > x].index.min() if pd.isna(first_larger_idx): # x比所有range都大,取最后一个sample sample_val = df_map['sample'].iloc[-1] elif first_larger_idx == 0: # x比第一个range还小,取第一个sample sample_val = df_map['sample'].iloc[0] else: # x落在前一个range和当前range之间,取对应sample sample_val = df_map['sample'].iloc[first_larger_idx] return x + sample_val # 测试单个x print(calculate_sum(4000)) # 输出6000 # 批量处理 df_x = pd.DataFrame({'x': [300, 4000, 150000]}) df_x['result'] = df_x['x'].apply(calculate_sum) print(df_x)
说明:
这个方法的好处是逻辑清晰,新手也能看懂,但数据量大的时候,apply的速度会比前两种方法慢一些,所以适合小数据集。
内容的提问来源于stack exchange,提问作者Manu Sharma
相关产品推荐
相关产品推荐

