2016-09-06 29 views
5

我負責的熊貓數據框中,有一個框架是這樣的:熊貓DENSE RANK

Year Value 
2012 10 
2013 20 
2013 25 
2014 30 

我想OVER(ORDER BY年)功能進行equialent到DENSE_RANK()。做一個這樣的額外的列:

Year Value Rank 
    2012 10 1 
    2013 20 2 
    2013 25 2 
    2014 30 3 

它是如何做到熊貓?

謝謝!

回答

6

使用pd.Series.rankmethod='dense'

df['Rank'] = df.Year.rank(method='dense').astype(int) 

df 

enter image description here

4

您可以將年份轉換爲分類,然後獲取他們的代碼(因爲它們是零索引,並且您希望初始值以您的示例中的一個爲開頭)添加一個代碼。

df['Rank'] = df.Year.astype('category').cat.codes + 1 

>>> df 
    Year Value Rank 
0 2012  10  1 
1 2013  20  2 
2 2013  25  2 
3 2014  30  3 
3

最快的解決方法是factorize

df['Rank'] = pd.factorize(df.Year)[0] + 1 

時序

#len(df)=40k 
df = pd.concat([df]*10000).reset_index(drop=True) 

In [13]: %timeit df['Rank'] = df.Year.rank(method='dense').astype(int) 
1000 loops, best of 3: 1.55 ms per loop 

In [14]: %timeit df['Rank1'] = df.Year.astype('category').cat.codes + 1 
1000 loops, best of 3: 1.22 ms per loop 

In [15]: %timeit df['Rank2'] = pd.factorize(df.Year)[0] + 1 
1000 loops, best of 3: 737 µs per loop 
+0

注意,你會想用'排序= TRUE;在調用'factorize',這將影響您的時間,以及(在我的隨機生成3M大數值DF,方法1,即使用'等級方法變成最快)。你認爲它的工作原因是因爲數組的非重複元素已經排序。 –

+0

是的,但它取決於數據是否排序。在樣本中進行排序,所以沒有必要。 – jezrael

+0

確實,這就是我所說的。因爲它已經排序,所以分解會更快。一般來說,數據不會被排序,因此分解和排序會返回不同的答案。我添加了評論,作爲未來讀者的警告,他們會盲目接管解決方案,而不檢查他們假設的工作條件。 –