如何在分组DataFrame中添加基于分组统计结果的条件计数列?
解决方法:给分组汇总统计添加条件计数列
这问题我之前也帮不少开发者处理过,用pandas的分组聚合/变换功能就能轻松搞定,我给你一步步拆解方案:
步骤1:获取每个CcyPair的75%分位数
首先,你提到的limitDataStats是通过.describe()生成的分组统计结果,那我们可以直接从里面提取每个币种对的75%分位数:
# 假设limitDataStats是groupby('CcyPair').describe()的结果 quant_75 = limitDataStats.xs('75%', level=1)['TradeNotional']
如果不想依赖已有的limitDataStats,也可以直接从原数据计算分位数,更灵活:
quant_75 = limitData.groupby('CcyPair')['TradeNotional'].quantile(0.75)
步骤2:计算每个CcyPair中TradeNotional超75%分位数的数量
这里有两种常用方法,你可以根据习惯选:
方法A:分组后直接apply计算
这种方法在分组内部完成条件判断和计数,逻辑紧凑:
count_over_75 = limitData.groupby('CcyPair').apply( lambda group: (group['TradeNotional'] > quant_75.loc[group.name]).sum() ).rename('CountOver75Pct')
group.name就是当前分组的CcyPair值,用来匹配对应的75%分位数sum()会把布尔值(True=1,False=0)相加,得到符合条件的数量
方法B:用transform广播分位数后筛选计数
这种方法更直观,适合新手调试:
# 给原数据每行添加对应分组的75%分位数 limitData['group_75pct'] = limitData.groupby('CcyPair')['TradeNotional'].transform( lambda x: x.quantile(0.75) ) # 筛选出超分位数的行,再按CcyPair分组计数 count_over_75 = limitData[limitData['TradeNotional'] > limitData['group_75pct']]\ .groupby('CcyPair').size().rename('CountOver75Pct')
步骤3:将计数列合并到sumStats中
因为count_over_75的索引是CcyPair,和sumStats的索引应该一致,直接用join合并即可:
sumStats = sumStats.join(count_over_75)
进阶:直接在分组聚合时生成所有统计项
如果你还没生成sumStats,可以一步到位,在分组聚合时就包含条件计数,不用事后合并:
sumStats = limitData.groupby('CcyPair')['TradeNotional'].agg( # 这里可以定义你需要的所有汇总统计 Total='sum', Mean='mean', Pct75=lambda x: x.quantile(0.75), # 直接在agg里添加条件计数 CountOver75Pct=lambda x: (x > x.quantile(0.75)).sum() )
这种方法更高效,避免了多次分组操作。
关于"向分组后的DataFrame添加基于分组结果的条件count"
其实上面的方法已经实现了这个需求:本质是基于分组内的计算结果(75%分位数),对分组内的数据做条件筛选后计数。你可以把这个逻辑封装成自定义函数,在agg或apply里调用,比如:
def count_over_quantile(series, q=0.75): quant_val = series.quantile(q) return (series > quant_val).sum() # 调用自定义函数 sumStats = limitData.groupby('CcyPair')['TradeNotional'].agg( Pct75=lambda x: x.quantile(0.75), CountOver75Pct=count_over_quantile )
内容的提问来源于stack exchange,提问作者CT00
相关产品推荐
相关产品推荐

