如何使用groupby过滤数据框中的重复项?

时间:2017-08-23 08:43:40

标签: python pandas dataframe group-by pandas-groupby

我有一个数据框df(cfg, x, rounds)是唯一的,其余的则不是。

      cfg   x     rounds  score  rewards  
0  f63c2c   a          1   0.01       10  
1  f63c2c   a          2   0.02       15  
2  f63c2c   b          3   0.03       30  
3  f63c2c   b          4   0.04       13  
4  f63c2c   b          5   0.05        8  
5  37fb26   a          1   0.08        8  
6  35442a   a          5   0.19        8  
7  bb8460   b          2   0.05        9  

我想以这样的方式过滤数据框,结果只有cfg, x, max(rounds)行,即

      cfg  x  rounds  score  rewards  
1  f63c2c  a       2   0.02       15  
4  f63c2c  b       5   0.05        8  
5  37fb26  a       1   0.08        8  
6  35442a  a       5   0.19        8  
7  bb8460  b       2   0.05        9  

为此,我确定使用的最大值:

gf = df.groupby(["cfg", "x"]).max().loc[:,["rounds"]]

但是,我还没有想出一种使用gf作为谓词提供程序来过滤df的方法。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

确实可以使用jsonMapper.constructCollectionType<Sku, MutableList<Sku>>() df.groupby

df.merge

并使用n [231]: df.groupby(['cfg', 'x']).rounds\ ...: .apply(np.max).reset_index()\ ...: .merge(df, on=['cfg', 'x', 'rounds']) Out[231]: cfg x rounds score rewards 0 35442a a 5 0.19 8 1 37fb26 a 1 0.08 8 2 bb8460 b 2 0.05 9 3 f63c2c a 2 0.02 15 4 f63c2c b 5 0.05 8

df.sort_values

<强>性能

In [237]: df.sort_values(by = ['cfg','x', 'rounds'],ascending = [True, True, False])\
            .drop_duplicates(subset = ['cfg', 'x'])
Out[237]: 
      cfg  x  rounds  score  rewards
6  35442a  a       5   0.19        8
5  37fb26  a       1   0.08        8
7  bb8460  b       2   0.05        9
1  f63c2c  a       2   0.02       15
4  f63c2c  b       5   0.05        8

使用df_test = pd.concat([df] * 100000) # Setup

df.merge

使用%timeit df_test.sort_values(by = ['cfg','x', 'rounds'],ascending = [True, True, False]) .drop_duplicates(subset = ['cfg', 'x']) 1 loop, best of 3: 229 ms per loop df.sort_values

df.drop_duplicates

答案 1 :(得分:1)

解决方案不是使用groupby(或者更准确地说,最简单的解决方案不是使用gorupby),而是使用drop_duplicates。 默认情况下,drop_duplicates会保留任何重复值的第一行,因此您可以对数据帧进行排序,然后使用以下内容删除重复项:

gf = df.sort_values(by = 'rounds',ascending = [True,False]).\
                                 drop_duplicates(subset = ['cfg','x'])

    cfg     x   rounds  score   rewards
6   35442a  a   5       0.19    8
5   37fb26  a   1       0.08    8
7   bb8460  b   2       0.05    9
4   f63c2c  b   5       0.05    8

您也可以等效地执行:

gf = df.sort_values(by = 'rounds',ascending = True).\
            drop_duplicates(subset = ['cfg','x'],keep = 'last')

编辑:Timeit

令人惊讶的是,我在答案中没有得到和coldspeed相同的时间:

df_test = pd.concat([df] * 100000) 
%timeit df_test.sort_values(by = ['cfg','rounds'],ascending = True).\
        drop_duplicates(subset = ['cfg'],keep = 'last')
%timeit df_test.groupby('cfg').rounds.apply(np.max).reset_index().\
        merge(my_df2, on=['cfg', 'rounds'])

62 ms ± 163 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
70.6 ms ± 28.4 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

这似乎并不取决于核心数量(我在8核和12核上发布它产生相同的排名),也不依赖于数据帧的大小(我尝试过使用df_test df的大小为10 000,10万和1 000 000,排名依旧)。

所以我猜它必须依赖于你的硬件,你只需要尝试这两种方法,看看哪种方法适合你的计算机。

感谢coldspeed指出

相关问题