如何根据情况汇总功能?

时间:2019-10-11 18:27:19

标签: python pandas

data = [['john', 'A01', 1],['john', 'A01', 1],['john', 'A01', 1],['john', 'B01', 0],['john', 'C01', 0],['katty', 'A01', 0],['katty', 'B01', 0]]

df = pd.DataFrame(data, columns = ['name', 'orderID','buying_channel']) 

purchase_channel = df.groupby('name').apply(lambda x: pd.Series({"buying_channel": sum((x.buying_channel)/(x.buying_channel.count()))}))

purchase_channel.head()

我要计算个人购买渠道,“ 1”是渠道,“ 0”是另一个渠道。 (1 =在线,0 =离线)

与其进行整体计算(得出的结果为0.6), 我想根据订单编号进行计算。

预期结果:

data2 = [['john', 0.33], ['katty', 0]]
df2 = pd.DataFrame(data2, columns = ['name','buying_channel'])
df2

因为“约翰”购买了3次,所以只有一次在线购买,其余的都是离线购买。 因此,如何根据orderID进行汇总?

谢谢

3 个答案:

答案 0 :(得分:1)

根据操作对象进行编辑:

import pandas as pd
data = [['john', 'A01', 1],['john', 'A01', 1],['john', 'A01', 1],['john', 'B01', 0],['john', 'C01', 0],['katty', 'A01', 0],['katty', 'B01', 0]]
df = pd.DataFrame(data, columns = ['name', 'orderID','buying_channel']) 
df_1 = df.merge(df.groupby(['name','orderID'],as_index=False)['buying_channel'].sum(),on=['name','orderID'],how='left')
df_1['purchase_channel'] = df_1['buying_channel_x']/df_1['buying_channel_y']
df_1 = df_1.drop(['buying_channel_y'],axis=1).fillna(0).rename(columns={'buying_channel_x':'buying_channel'}).groupby('name')['purchase_channel'].max()
print(df_1)

输出:

name
john     0.333333
katty    0.000000
Name: purchase_channel, dtype: float64

答案 1 :(得分:1)

您可以在name, orderID上放置重复项,并在buying_channel上取平均值:

(df.drop_duplicates(['name','orderID'])
   .groupby('name', as_index=False)
   .buying_channel.mean()
)

输出:

    name  buying_channel
0   john        0.333333
1  katty        0.000000

答案 2 :(得分:0)

我认为.value_counts(normalize=True)可以达到您想要的目标。

Docs to value_counts()

希望这会有所帮助!如果这不是您想要的内容,请澄清一下问题,因为我觉得有些困惑。这也将帮助其他可能有更好想法的人来解决您的问题。

EDIT1:

问题编辑后,我认为您可以通过以下方式实现:

df.groupby('name')['buying_channel'].apply(lambda x: x.value_counts(normalize=True)[1] if (x==1).sum() else 0)

输出:

name
john     0.6
katty    0.0
Name: buying_channel, dtype: float64

在lambda中,在归一化的value_counts()之后,我为1选择结果,获得每个名称出现1的次数的比例。如果没有给定名称的1,例如'katty',则else子句避免了错误。

如果需要,可以从末尾附加.to_frame()的数据帧中获取数据帧。

希望这会有所帮助!