Вы должны использовать numpy.partition
, чтобы избежать полной сортировки. Это уменьшит временную сложность нахождения трех максимальных значений от O(nlogn)
до O(n)
, что будет иметь огромное значение для больших фреймов данных:
np.sum(np.partition(df.values, -3)[:, -3:], 1)
df.assign(max3=np.sum(np.partition(df.values, -3)[:, -3:], 1))
0 1 2 3 4 max3
0 591949 2575703 22479693 2202865 499835 27258261
1 2705 11426 339913 5438 1016 356777
2 18 119 4162 18 0 4299
3 264 1213 14999 246 116 16476
4 0 35 1292 10 0 1337
5 0 0 1442 0 0 1442
6 0 28 5596 20 0 5644
7 0 10 102 56 0 168
8 33 0 1224 17 0 1274
9 39 198 9505 62 35 9765
Задержка
In [411]: df = pd.DataFrame(np.random.rand(5000, 5000))
In [412]: %timeit np.sum(np.sort(df.values)[:,-3:],axis=1)
1.69 s ± 92.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [413]: %timeit np.sum(np.partition(df.values, -3)[:, -3:], 1)
364 ms ± 23.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)