首页 > 解决方案 > 按键分组并使用自定义条件进行聚合

问题描述

我有如下数据框:

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 而不是手动迭代?

标签: pythonpandas

解决方案


这是一种使用df.groupbywith value counts withnormalize=True检查每组中值的 pct 的方法,然后检查 % 是否大于或等于 0.75 ,然后使用np.where设置返回 Tue to 的值mixed,最后df.groupby()withidxmax将返回 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

推荐阅读