在其他列上使用多个条件执行 Pandas groupby.apply 的更快替代方法

Faster alternative to perform Pandas groupby.apply with a multiple conditions on other columns

假设我们有以下数据框:

df = pd.DataFrame({"ID": [20, 10, 20, 20, 10, 10, 10, 20, 20, 20, 10, 20, 30, 30], 
                   "Revenue": [90, 89, 80, 95, 99, 59, 70, 95, 78, 85, 82, 71, 78, 88],
                   "Chance": [True, True, False, True, False, False, False, True, True, True, False, True, True, False],
                   "City": ["Strasbourg", "Koln", "Alger", "Casa", "Mosco", "London", "Montpellier", "Barcelone", "Lyon", "Madrid", "Milan", "NYC", "Torino", "Paris"]
                  })

df 应按 ID 分组,并应创建 2 列,如下所示:
-'NotAccepted' 城市:'Revenue' 低于 84 OR 'Chance' 的城市是假的:
-'Accepted' 其余城市。
我必须将所有 'Accepted' 和 'NotAccepted' 城市的名称连接到这些列中。 (请查看下面的最终照片)

我的解决方法如下:

df_result=df.groupby('ID').apply(lambda g: pd.Series({
    'NotAccepted': [','.join(g['City'][(g['Chance'] == False) | (g['Revenue'] < 84)])],                                          
    'Accepted': [','.join(g['City'][(g['Chance'] == True) & (g['Revenue'] >= 84)])],
                                             })).reset_index()

真正的df其实很大,需要很长时间才能group/apply。 是否有比我的解决方案更快的替代方案?谢谢。

你可以在groupby

之前建一个col
df['new'] = np.where((df['Chance'] == False) | (df['Revenue'] < 84),'NotAccepted','Accepted')
out = df.groupby(['ID','new'])['City'].agg(list).unstack(fill_value=[])

使用 Dask Groupby - 我遇到了类似的问题并获得了大约 1 个数量级的加速。这允许您 运行 跨多个 CPU 而不是单线程绑定。

https://examples.dask.org/dataframes/02-groupby.html

我想也有发送到 GPU/multi-node 的方法。