大熊猫用groupby爆炸列很慢

时间:2020-06-26 18:36:47

标签: python pandas pandas-groupby

我有一个df和一列parsed xml,其中包含具有已解析属性的每一行的字典列表。看起来像这样:

   id  type  length  parsed    
0  1   A     144     [{'key1':'value1'},{'key1':'value2', 'key2':'value3'},...]
1  1   B     20      [{'key1':'value4'},{'key2':'value5'},...]
2  4   A     54      [{'key3':'value6'},...]

我正在使用以下内容将这些词典扩展到其他列中。

s = df['parsed xml'].explode()
t = (df.join(pd.DataFrame(s.tolist(), index = s.index).groupby(level=0).agg(lambda x: x.dropna().tolist()), /
    lsuffix = '_x', rsuffix = '_y')).applymap(lambda x: x[0] if (type(x)==list and len(x)==1) else x)

这给了我这样的数据框架,这就是我想要的:

   id  type  length  key1             key2     key3
0  1   A     144     [value1,value2]  value3
1  1   B     20      value4           value5
2  4   A     54                                value6

问题在于,到达此数据帧的代码需要5,000条记录花费大约45秒的时间,但似乎永远持续下去,因为它用于12,000条记录。似乎是groupby引起的,但是可以提高效率吗?

1 个答案:

答案 0 :(得分:3)

您可以使用stackunstack稍微改变方法以进行优化,并仅对您创建的列执行applymap。像这样:

s = df['parsed'].explode()
df_join = (pd.DataFrame(s.tolist(), index = s.index)
             .stack()
             .groupby(level=[0,1])
             .agg(list)
             .apply(lambda x: x[0] if len(x)==1 else x)
             .unstack(fill_value='')
          )
t = df.join(df_join)
print (t) # I did not used exactly your input
  id                                             parsed              key1  \
0  a  [{'key1': 'value1'}, {'key1': 'value2', 'key2'...  [value1, value2]   
1  b           [{'key1': 'value4'}, {'key2': 'value5'}]            value4   
2  c                               [{'key3': 'value6'}]                     

     key2    key3  
0  value3          
1  value5          
2          value6  

现在在性能方面,我看到像这样的3行数据框的性能提高了2,但是随着尺寸的增加,性能提高了(3K行的速度提高了6倍)。速度的提高将取决于您在列解析中每个列表中具有的元素数量以及不同键的数量