簡體   English   中英

對每一行進行排序,然后從數據框中選擇前三個值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM