2016-09-06 48 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

确实,这就是我所说的。因为它已经排序,所以分解会更快。一般来说,数据不会被排序,因此分解和排序会返回不同的答案。我添加了评论,作为未来读者的警告,他们会盲目接管解决方案,而不检查他们假设的工作条件。 –