使用双groupby
- 第二通过a
水平MultiIndex
:
s = df.groupby('a')['b'].nlargest(3).groupby(level='a').sum()
print (s)
a
1 16
2 18
Name: b, dtype: int64
但对我来说是更好:
df.groupby('a')['b'].nlargest(3).sum(level=0)
谢谢Nickil Maveli
。
编辑:如果需要顶3
再次,使用Series.nlargest
:
df = pd.DataFrame({'a': [1, 1, 2, 3, 2, 2, 1, 3, 4, 3, 4],
'b': [5, 7, 3, 3, 5, 6, 4, 3, 7, 4, 5]})
print (df)
a b
0 1 5
1 1 7
2 2 3
3 3 3
4 2 5
5 2 6
6 1 4
7 3 3
8 4 7
9 3 4
10 4 5
df = df.groupby('a')['b'].nlargest(3).sum(level=0).nlargest(3)
print (df)
a
1 16
2 14
4 12
Name: b, dtype: int64
时序:
np.random.seed(123)
N = 1000000
L2 = np.arange(100)
df = pd.DataFrame({'b':np.random.randint(20, size=N),
'a': np.random.choice(L2, N)})
print (df)
In [22]: %timeit df.groupby('a')['b'].apply(lambda x: x.nlargest(3).sum())
10 loops, best of 3: 125 ms per loop
In [23]: %timeit df.groupby('a')['b'].nlargest(3).groupby(level='a').sum()
10 loops, best of 3: 121 ms per loop
In [29]: %timeit df.groupby('a')['b'].nlargest(3).sum(level=0)
10 loops, best of 3: 121 ms per loop
np.random.seed(123)
N = 1000000
L2 = list('abcdefghijklmno')
df = pd.DataFrame({'b':np.random.randint(20, size=N),
'a': np.random.choice(L2, N)})
print (df)
In [19]: %timeit df.groupby('a')['b'].apply(lambda x: x.nlargest(3).sum())
10 loops, best of 3: 97.9 ms per loop
In [20]: %timeit df.groupby('a')['b'].nlargest(3).groupby(level='a').sum()
10 loops, best of 3: 96.5 ms per loop
In [31]: %timeit df.groupby('a')['b'].nlargest(3).sum(level=0)
10 loops, best of 3: 97.9 ms per loop
np.random.seed(123)
N = 1000000
L2 = list('abcde')
df = pd.DataFrame({'b':np.random.randint(20, size=N),
'a': np.random.choice(L2, N)})
print (df)
In [25]: %timeit df.groupby('a')['b'].apply(lambda x: x.nlargest(3).sum())
10 loops, best of 3: 82 ms per loop
In [26]: %timeit df.groupby('a')['b'].nlargest(3).groupby(level='a').sum()
10 loops, best of 3: 81.9 ms per loop
In [33]: %timeit df.groupby('a')['b'].nlargest(3).sum(level=0)
10 loops, best of 3: 82.5 ms per loop
有趣的是,看起来时间取决于团体的规模,看我的时间。你可以在你的电脑上测试它吗? – jezrael
看来,如果群体很大 - 你只有'2'大群体,而我'15''申请'更快。 – jezrael
你说得对。我得到了138比140ms。 'apply'对你的测试用例表现稍微好一些。 – Zero