2014-11-03 51 views
10

我有一個擁有不同子組的子熊貓數據框。在熊貓數據框的子組中排列行的更快方法

df = pd.DataFrame({ 
    'id':[1, 2, 3, 4, 5, 6, 7, 8], 
    'group':['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], 
    'value':[.01, .4, .2, .3, .11, .21, .4, .01] 
    }) 

我想找到與發言權組的每個ID的等級,較低的值是更好的。在上面的例子中,在A組中,Id 1的秩爲1,Id 2的秩爲4.在組B中,Id 5的秩爲2,Id 8的秩爲1,所以上。

現在我通過評估等級:

  1. 按值排序。

    df.sort('value', ascending = True, inplace=True)

  2. 創建排名器函數(它假定已經排序變量)

    def ranker(df): df['rank'] = np.arange(len(df)) + 1 return df

  3. 分別塗抹在各組的排名器功能:

    df = df.groupby(['group']).apply(ranker)

這個過程有效,但是當我在數百萬行數據上運行它時,它確實很慢。有沒有人有任何想法如何使更快的排序功能。

回答

19

排名是cythonized所以應該是非常快。你可以通過相同的選項df.rank() hererank的文檔。正如你所看到的,通過參數method可以用五種不同的方式之一進行搶七。

它也有可能你只是想組.cumcount()

In [12]: df.groupby('group')['value'].rank(ascending=False) 
Out[12]: 
0 4 
1 1 
2 3 
3 2 
4 3 
5 2 
6 1 
7 4 
dtype: float64 
+0

當然!有它的功能!也就是說,它和我上面的函數並不完全一樣,因爲如果有一個值綁定,我的函數將隨機給一個id比另一個id具有相同的值更高的等級。儘管.rank()處理相同值的方式相當明智,但對於我的目的而言,我需要我的函數生成的輸出。謝謝你的幫助! – 2014-11-03 19:56:36

+0

我更新了替代方案。 – Jeff 2014-11-03 21:25:35

9

使用一個大的DataFrame(1300萬行),該方法與groupby排序最多我的8GB內存,它花了很長時間。我在內存中發現了一個不太貪心的解決方法,我只是爲了防備:

df.sort_values('value') 
tmp = df.groupby('group').size() 
rank = tmp.map(range) 
rank =[item for sublist in rank for item in sublist] 
df['rank'] = rank