提高 groupby() 性能

Improving groupby() performance

原始数据框是:

import pandas as pd
array = {'id': [1, 1, 1, 1, 2, 3],
         'color': ['yellow', 'red', 'yellow', 'red', 'yellow', 'white']}
df = pd.DataFrame(array)
df

id          color
1           yellow
1           red
1           yellow
1           red
2           yellow
3           white

我已经使用 get_dummies 将其转换为以下数据框:

df = pd.get_dummies(df, prefix='', prefix_sep='')
df

   id  red  white  yellow
0   1    0      0       1
1   1    1      0       0
2   1    0      0       1
3   1    1      0       0
4   2    0      0       1
5   3    0      1       0

我要 groupby() 列 'id':

df.groupby(['id']).max()

    red  white  yellow
id                    
1     1      0       1
2     0      0       1
3     0      1       0

但是,我的原始数据框是 8,000 行 x 1,500,000 列,这使得此操作太慢了。

关于如何让它更快的任何想法?

更新

根据您的原始数据框,我将唯一化数据框并稍后对其进行透视(或热编码)。这样,您就可以完全避免任何后续聚合。

df_unique = df.drop_duplicates()
df_unique["val"] = 1
df_unique
    id  color   val
0   1   yellow  1
1   1   red     1
4   2   yellow  1
5   3   white   1

df_unique.set_index("id").pivot(columns="color").fillna(0)
    red     white   yellow
id          
1   1.0     0.0     1.0
2   0.0     0.0     1.0
3   0.0     1.0     0.0

编码选择

请尝试重塑您的数据(这也很耗时),但可能比您当前的宽格式更快:

# first approach using melt.groupby.max 
pd.melt(df, id_vars = 'id').groupby(["id", "variable"]).max()

# second approach using melt.sort.groupby.first
pd.melt(df, id_vars = 'id').sort_values(by="variable", ascending=True).groupby(["id", "variable"]).first()

之后您可以运行再次保留所需的形状:

melted_and_aggregated_df.reset_index(level=["variable"]).pivot(columns=["variable"], values="value")

数据大小

除了纯粹的编码效率,尽量减少你的数据。

  • 如果有些组只有一行,您应该只对其他组使用 max/first 方法,然后再合并结果。
  • 实际上有150万种颜色吗?听起来很大。你真的需要所有这些还是可以先reduced/aggregated?