按键分组并使用自定义条件聚合

2024-09-28 13:25:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我的数据框架如下:

df = pd.DataFrame([['A', 'a', 'web'],
                   ['A', 'b', 'mobile'],
                   ['B', 'c', 'web'],
                   ['C', 'd', 'web'],
                   ['D', 'e', 'mobile'],
                   ['D', 'f', 'web'],
                   ['D', 'g', 'web'],
                   ['D', 'g', 'web']],

columns=['seller_id', 'item_id', 'selling_channel'])

它显示了已售出的商品,其中包含关于谁是卖家以及用于销售商品的销售渠道(在上面的示例中,可以是网络或移动渠道,但实际数据中有更多潜在渠道)的信息

我想确定哪一个销售渠道是给定销售id的主要渠道,但还有其他限制:

  1. 如果其中一个渠道用于75%或以上的销售,则该渠道将是主要渠道
  2. 如果没有一个通道至少有75%,则主通道的名称应为mixed

因此,对于上面的输入,我期待以下输出:

df = pd.DataFrame([['A', 'mixed'],
                   ['B', 'web'],
                   ['C', 'web'],
                   ['D', 'web']],

columns=['seller_id', 'main_selling_channel'])

现在,我正在通过手动迭代每个数据帧的行来构建映射,其中每个卖方id列出了每个通道以及它的出现次数。然后我再次迭代该数据,以确定哪个通道是主通道。但是当我有10k行输入时,这个手动迭代已经花费了很多时间——而实际数据包含数百万条输入

我想知道是否有什么有效的方法可以用pandas api而不是手动迭代


Tags: columns数据webiddataframedfchannel手动
2条回答

这不是一种优雅的方式,但却能做到:

temp = df.groupby(["seller_id", "selling_channel"])\
         .count().reset_index()\
         .groupby("seller_id")["item_id"].agg(["max", "sum"])
temp

    max sum
seller_id       
A   1   2
B   1   1
C   1   1
D   3   4

top_channel = df.groupby("seller_id")["selling_channel"]\
                .apply(lambda x: x.value_counts().index[0])
top_channel

seller_id
A    mobile
B       web
C       web
D       web

temp["selling_channel"] = top_channel
final = temp.apply(lambda r: "mixed" if r["max"]/r["sum"]<0.75 else r["selling_channel"], axis=1).to_frame().reset_index()
final.columns = ["seller_id", "main_selling_channel"]

    seller_id   main_selling_channel
0   A   mixed
1   B   web
2   C   web
3   D   web

这里有一种方法,使用df.groupbynormalize=True的值计数来检查每组值的pct,然后检查%是否大于或等于0.75,然后使用np.where设置返回Tue到mixed的值,最后df.groupby()idxmax将返回1个值,否则mixed

a = (df.groupby('seller_id')['selling_channel'].value_counts(normalize=True).ge(0.75)
       .rename('Pct').reset_index())

out = (a.assign(selling_channel=np.where(a['Pct'],a['selling_channel'],'mixed'))
       .loc[lambda x: x.groupby('seller_id')['Pct'].idxmax()].drop('Pct',1))

print(out)

  seller_id selling_channel
0         A           mixed
2         B             web
3         C             web
4         D             web

相关问题 更多 >

    热门问题