首页 > 解决方案 > 根据条件对 groupby 的值求和

问题描述

我正在处理一些旧的 kagle 竞赛的数据集,

我想从其中一张表中进行一些聚合:

要知道哪一天的折扣更大,我的预期输出是这样的:

在此处输入图像描述 在此处输入图像描述

为此,我尝试使用以下代码:

coupon_list[[ 'USABLE_DATE_MON', 'USABLE_DATE_TUE', 'USABLE_DATE_WED',
       'USABLE_DATE_THU', 'USABLE_DATE_FRI', 'USABLE_DATE_SAT',
       'USABLE_DATE_SUN','DISCOUNT_PRICE']].melt("DISCOUNT_PRICE").groupby("variable").agg({"DISCOUNT_PRICE":sum,"value":sum})

但是对于该聚合,disscount_price 是所有表的平均值,而不是每天的平均值。

在此处输入图像描述

为了解决这个问题,我创建了一个新表:

coupon_list_usable["DISCOUNT_PRICE"] =  coupon_list_usable.apply(lambda x: x.DISCOUNT_PRICE if x.value==1 else 0,axis=1 )

coupon_list_usable.groupby("variable").agg({"DISCOUNT_PRICE":sum,"value":sum}).reset_index()[["variable","DISCOUNT_PRICE"]].set_index("variable").plot.bar()

但这不是一个pythonic解决方案,是否可以在 groupby 本身中做到这一点?

标签: pythonpandasgroup-by

解决方案


使用queryforfor 过滤行1和用于聚合使用GroupBy.sum

注意:dropna这里不能使用,因为2天数列的数据中也有值。

s = (coupon_list.melt("DISCOUNT_PRICE")
                 .query('value == 1')
                 .groupby("variable")['DISCOUNT_PRICE']
                 .sum())

s.plot.bar()

您还可以使用sreindex或通过ordered Categoricals 更改天数的顺序:

days = ['USABLE_DATE_MON', 'USABLE_DATE_TUE', 'USABLE_DATE_WED',
       'USABLE_DATE_THU', 'USABLE_DATE_FRI', 'USABLE_DATE_SAT',
       'USABLE_DATE_SUN']

s = (coupon_list.melt("DISCOUNT_PRICE")
                 .query('value == 1')
                 .groupby("variable")['DISCOUNT_PRICE']
                 .sum()
                 .reindex(days))

days = ['USABLE_DATE_MON', 'USABLE_DATE_TUE', 'USABLE_DATE_WED',
       'USABLE_DATE_THU', 'USABLE_DATE_FRI', 'USABLE_DATE_SAT',
       'USABLE_DATE_SUN']

s = (coupon_list.melt("DISCOUNT_PRICE", var_name='days', value_name='data')
                .assign(days = lambda x: pd.Categorical(x['days'], 
                                                        ordered=True, 
                                                        categories=days))
                .query('value == 1')
                .groupby("days")['DISCOUNT_PRICE']
                .sum())

样品

coupon_list = pd.DataFrame({
         'USABLE_DATE_MON':[np.nan,np.nan,np.nan,1,1,np.nan],
         'USABLE_DATE_TUE':[1,np.nan,1,np.nan,1,np.nan],
         'USABLE_DATE_WED':[1,np.nan,np.nan,np.nan,1,1],
         'USABLE_DATE_THU':[1,1,np.nan,1,1,np.nan],
         'USABLE_DATE_FRI':[np.nan,1,2,np.nan,1,np.nan],
         'USABLE_DATE_SAT':[1,1,np.nan,1,1,2],
         'USABLE_DATE_SUN':[1,np.nan,1,1,1,1],
         'DISCOUNT_PRICE':[2,3,6,2,2,4],
})
print (coupon_list)
   USABLE_DATE_MON  USABLE_DATE_TUE  USABLE_DATE_WED  USABLE_DATE_THU  \
0              NaN              1.0              1.0              1.0   
1              NaN              NaN              NaN              1.0   
2              NaN              1.0              NaN              NaN   
3              1.0              NaN              NaN              1.0   
4              1.0              1.0              1.0              1.0   
5              NaN              NaN              1.0              NaN   

   USABLE_DATE_FRI  USABLE_DATE_SAT  USABLE_DATE_SUN  DISCOUNT_PRICE  
0              NaN              1.0              1.0               2  
1              1.0              1.0              NaN               3  
2              2.0              NaN              1.0               6  
3              NaN              1.0              1.0               2  
4              1.0              1.0              1.0               2  
5              NaN              2.0              1.0               4  

days = ['USABLE_DATE_MON', 'USABLE_DATE_TUE', 'USABLE_DATE_WED',
       'USABLE_DATE_THU', 'USABLE_DATE_FRI', 'USABLE_DATE_SAT',
       'USABLE_DATE_SUN']

s = (coupon_list.melt("DISCOUNT_PRICE", var_name='days', value_name='data')
                .assign(days = lambda x: pd.Categorical(x['days'], 
                                                        ordered=True, 
                                                        categories=days))
                .query('data == 1')
                .groupby("days")['DISCOUNT_PRICE']
                .sum())

print (s)
days
USABLE_DATE_MON     4
USABLE_DATE_TUE    10
USABLE_DATE_WED     8
USABLE_DATE_THU     9
USABLE_DATE_FRI     5
USABLE_DATE_SAT     9
USABLE_DATE_SUN    16
Name: DISCOUNT_PRICE, dtype: int64

s.plot.bar()

图形


推荐阅读