如何为Pandas数据框的各阈值找到left值小于它的首个ID?
问题描述
现有如下结构的Pandas数据框:
ID ST ... csum left 0 0 AK ... 4.293174e+05 760964.996900 1 1 AK ... 4.722491e+06 760535.679500 2 2 AK ... 8.586347e+06 760149.293900 3 3 AK ... 2.683233e+07 758324.695200 4 4 AK ... 2.962290e+07 758045.638900 .. ... ... ... ... ... 111 111 AK ... 7.609006e+09 107.329336 112 112 AK ... 7.609221e+09 85.863469 113 113 AK ... 7.609435e+09 64.397602 114 114 AK ... 7.609650e+09 42.931735 115 115 AK ... 7.610079e+09 0.000000
需要针对阈值列表 thresholds = [0,50,100,150,200,250,500,1000] 中的每个值,找到left列数值小于该阈值的首个ID,最终得到如下结果表:
threshold ID 0 115 50 114 100 112 150 100 200 100 250 99 500 78 1000 77
解决方案
方法1:利用数据排序特性的高效向量化实现
观察数据可知,left列是严格递减排列的(ID越大,left值越小),可以结合numpy的向量化搜索快速定位目标ID,效率远高于循环筛选:
import pandas as pd import numpy as np # 假设你的数据框名为df thresholds = [0,50,100,150,200,250,500,1000] # 提取列数据为numpy数组 left_arr = df['left'].values id_arr = df['ID'].values # 对每个阈值,找到第一个满足left < threshold的索引 # 因为left递减,np.argmax会返回第一个符合条件的位置 indices = [np.argmax(left_arr < thresh) for thresh in thresholds] # 构造结果数据框 result = pd.DataFrame({ 'threshold': thresholds, 'ID': id_arr[indices] }) # 可选:调整格式让阈值右对齐,和示例一致 display(result.style.set_properties(**{'text-align': 'right'}))
方法2:通用循环实现(适用于任意排序的数据)
如果数据框的left列无序,或需要更通用的写法,可以遍历每个阈值,用布尔索引筛选后取首个ID:
thresholds = [0,50,100,150,200,250,500,1000] result_rows = [] for thresh in thresholds: # 筛选left小于阈值的行,取第一个ID target_id = df[df['left'] < thresh]['ID'].iloc[0] result_rows.append({'threshold': thresh, 'ID': target_id}) result = pd.DataFrame(result_rows)
注意事项
- 方法1仅适用于
left列递减的场景,若数据无序请使用方法2; - 方法2中如果存在没有满足
left < threshold的行,iloc[0]会抛出索引错误,可添加异常处理逻辑(比如用.head(1).values[0]替代,或加入try-except)。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

