2017-07-31 68 views
2

Rdata.table,您可以按列返回一個任意長度的向量的列執行操作。大熊貓相當於data.table

假設,我想收集一列中的前5個值,按另一列分組。 data.table負責粘合子組。

require(magrittr) 
library(data.table) 

n <- 100 
DT <- data.table(A = rnorm(n), B = sample(letters[1:4], n, replace = TRUE)) 
DT[, sort(B, decreasing = TRUE) %>% head(5), by = B] 

隨着Pythonpandas,我嘗試了不同的策略:

import pandas as pd 
import random 

n = 100 
df = pd.DataFrame({'A' : np.random.randn(n), 
        'B' : [random.choice(list('abc')) for i in range(n)]}) 
# first try : 
groups = df.groupby('B') 
groups.apply(lambda x : sorted(x['A'], reverse=False)[:5]) 

但這種方法還給一個3X1(假設我有3組)數據框與行內的名單,這不看起來很奇怪,因爲排序會返回一個列表對象。

# second try: 
groups.apply(lambda x : np.sort(x['A'])[-5:]) 

沒有更確切的結論。

我發現,但看起來真的詳細到我的解決方案,意味着迭代組:

dfs = [] 
for g in groups: 
    dfs.append(g[1].sort_values('A').tail(5)) 
pd.concat(dfs).sort_values('B') 

什麼,我能爲執行此操作更優雅的方式使用任何想法? 謝謝,我一直在尋找一個Python的解決方案...

+0

怎麼是'df.groupby( 'B')申請(拉姆達x:x.sort_values(by ='A',ascending = False).head(5))'? – Abdou

+0

Fwiw,更多的標準R代碼是'DT [order(-A),head(.SD,5),by = B]' – Frank

+0

這確實有幫助。好點子 ! – user8131

回答

2

IIUC:

n = 100 
df = pd.DataFrame({'A' : np.random.randn(n), 
        'B' : [np.random.choice(list('abc')) for i in range(n)]}) 
groups = df.groupby('B') 
groups.apply(lambda x : x['A'].sort_values().tail(5)) 

輸出:

B  
a 97 1.068696 
    26 1.142186 
    35 1.222854 
    18 1.379540 
    43 1.466977 
b 46 1.185664 
    94 1.206992 
    49 1.464562 
    81 1.609808 
    51 1.814868 
c 50 1.129484 
    8  1.155544 
    95 1.250349 
    9  1.337286 
    90 1.581751 
Name: A, dtype: float64 
+0

這絕對可以解決問題。感謝你和Abou的評論! – user8131

+0

不客氣。 –

+0

對於與data.table完全相同的輸出,我需要將此結果存儲在變量reset_index中,並刪除已添加的列'level_1'(具有最高值的行索引)...我是否正確? – user8131