我有一个数据框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的方法。有什么想法吗?
答案 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指出