根据条件在groupby上求和的值

时间:2018-12-23 06:32:25

标签: python pandas group-by

我正在处理一些古老的kagle算术的数据集

我想从其中一张表中进行一些汇总:

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

enter image description here enter image description here

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

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是所有表的平均值,而不是每日平均值。

enter image description here

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

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本身来做到这一点?

1 个答案:

答案 0 :(得分:3)

query用于带有1的过滤器行以及总计GroupBy.sum的使用:

注意:此处的dropna不能使用,因为“天”列的数据中也有2个值。

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

s.plot.bar()

您还可以通过reindexordered Categorical来更改日期的顺序:

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()

graph