[英]Capture the first three unique values from each row in a pandas dataframe
[英]Sorting each row and select the top three values from a dataframe
我有一個看起來像這樣的數據框:
device_id s2 s41 s47 s14
30 0 0 0 0.003
125 0 0 0 0
32 0 0 0 0
45 0 0 0 0
目的是從每行中獲得3個最高的s,如果存在匹配項,則選擇最大索引。 例如,對於第一行,s2,s41和s47之間存在匹配項,因此將與s41一起選擇s47。 因此從第1行選擇的是s14,s47和s41。 有超過200萬條記錄和超過250 s的記錄,因此我需要一種有效的方法來執行此操作。 我已經嘗試過迭代,然后對每一行進行排序,但是它很慢,並且所有數據花費一個多小時。
最終目標將是在字典中搜索s(s14,s47,s41),其中這些值是關鍵字,並從中獲取適當的值。
有人可以幫助我有效地做到這一點。 謝謝
我會用heapq的nlargest
:
In [11]: df
Out[11]:
device_id s2 s41 s47 s14
0 30 0 0 0 0.003
1 125 0 0 0 0.000
2 32 0 0 0 0.000
3 45 0 0 0 0.000
In [12]: nlargest(3, df.columns[1:], key=lambda x: int(x[1:]))
Out[12]: ['s47', 's41', 's14']
In [13]: df[["device_id"] + nlargest(3, df.columns[1:], key=lambda x: int(x[1:]))]
Out[13]:
device_id s47 s41 s14
0 30 0 0 0.003
1 125 0 0 0.000
2 32 0 0 0.000
3 45 0 0 0.000
注意:如果device_id是索引,則要容易一些:
In [21]: df1
Out[21]:
s2 s41 s47 s14
device_id
30 0 0 0 0.003
125 0 0 0 0.000
32 0 0 0 0.000
45 0 0 0 0.000
In [22]: df1[nlargest(3, df1.columns, key=lambda x: int(x[1:]))]
Out[22]:
s47 s41 s14
device_id
30 0 0 0.003
125 0 0 0.000
32 0 0 0.000
45 0 0 0.000
我不認識熊貓,但我知道它是基於numpy的,因此這里是一個numpy解決方案。 它使用argpartition有效地獲取每行中最大4的索引。 不幸的是,numpy使用的算法不穩定,因此如果這四個中的最小兩個相等,我們必須進行完整排序,排序使我們可以選擇一個穩定的算法。
代碼(無法在我的裝置上檢查2m行b / c內存,但是0.5m需要2秒鍾左右的時間):
import numpy as np
def stable_high_3(data):
n, m = data.shape
high_4 = np.argpartition(data, np.arange(m-4, m), axis=-1)[:, -4:]
must_check = np.where(data[np.arange(n), high_4[:, 0]]
== data[np.arange(n), high_4[:, 1]])[0]
high_4[must_check, -3:] = np.argsort(data[must_check], axis=-1,
kind='mergesort')[:, -3:]
return high_4[:, -3:]
data = np.reshape(np.arange(30)%5, (-1, 6))
print(data)
print(stable_high_3(data))
data = np.reshape(np.arange(256*2**18)%50, (-1, 256))
stable_high_3(data)
版畫
[[0 1 2 3 4 0]
[1 2 3 4 0 1]
[2 3 4 0 1 2]
[3 4 0 1 2 3]
[4 0 1 2 3 4]]
[[2 3 4]
[1 2 3]
[5 1 2]
[0 5 1]
[4 0 5]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.