Python如何基于固定阈值对pandas DataFrame数据实现分箱处理
你的需求属于动态贪心分箱逻辑,pandas内置的cut和qcut确实不直接适配这类场景:cut是基于预定义的固定区间分箱,qcut是基于分位数区间分箱,而你的分箱起始点由前一个分箱的结束位置动态决定,需要自定义逻辑实现。
以下是可直接运行的实现方案,输出完全符合你的预期:
import pandas as pd # 示例数据 df = pd.DataFrame({'Marker': ['m1','m2','m3','m4','m5','m6','m7','m8','m9','m10'], 'Position': [0,0.5,0.6,2,5,7,8.4,15,16,17]}) threshold = 5 # 初始化分箱参数 current_start = df['Position'].iloc[0] bin_id = 1 bin_ids = [] for pos in df['Position']: # 当前位置和分箱起始位置差值超过阈值,就新开一个分箱 if pos - current_start > threshold: current_start = pos bin_id += 1 bin_ids.append(bin_id) # 给原表增加分箱编号列 df['bin_id'] = bin_ids # 按分箱分组提取Marker列表 bin_result = df.groupby('bin_id')['Marker'].apply(list).to_dict() # 打印输出 for bin_num, markers in bin_result.items(): print(f"bin{bin_num} = {markers}")
运行输出:
bin1 = ['m1', 'm2', 'm3', 'm4', 'm5'] bin2 = ['m6', 'm7'] bin3 = ['m8', 'm9', 'm10']
如果处理的数据量较大,想避免循环提升效率,可以用向量化操作实现:
import pandas as pd import numpy as np threshold = 5 # 生成动态分箱编号 df['bin_id'] = 1 df['bin_id'] = df['bin_id'].where(df['Position'] - df['Position'].shift(1).where(df['Position'].diff() > threshold).ffill().fillna(df['Position'].iloc[0]) <= threshold, df['bin_id'].cumsum()) # 分组提取结果 bin_result = df.groupby('bin_id')['Marker'].apply(list).to_dict()
内容的提问来源于stack exchange,提问作者Amilovsky
相关产品推荐
相关产品推荐

