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进行汇总?
谢谢
答案 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)
可以达到您想要的目标。
希望这会有所帮助!如果这不是您想要的内容,请澄清一下问题,因为我觉得有些困惑。这也将帮助其他可能有更好想法的人来解决您的问题。
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()
的数据帧中获取数据帧。
希望这会有所帮助!