2017-03-17 68 views
0

我有類似的國家和年份索引以下數據框:獲得通過數據框列排序索引值

import pandas as pd 

d = pd.DataFrame(index=['CA', 'WA', 'OR', 'NV']) 
d[2015]=[100, 200, 40, 75] 
d[2016]=[1000, 20, 25, 12] 
print d 
    2015 2016 
CA 100 1000 
WA 200 20 
OR 40 25 
NV 75 12 

我想要一個新的數據幀,其中指數是每個國家當年的排名,和值是按排名順序的狀態。

pd.DataFrame([d.sort_values(x).index for x in d.columns], index=d.columns, columns=range(1,len(d)+1)).transpose() 
Out[57]: 
    2015 2016 
1 OR NV 
2 NV WA 
3 CA OR 
4 WA CA 

有沒有得到這個輸出的更清潔的方式:

如下我可以得到的輸出?

回答

3

您可以使用argsort,它返回的每個索引列進行排序,其應用於指數給出升序排名指數:

d.apply(lambda x: x.index[x.argsort()]) 

enter image description here

,你可以,如果你不叫reset_index(drop=True)不想保留數據框中的原始索引。

+0

現在到複雜的事情(對不起,我沒有最初認爲這種例外)。假設我在初始數據框中缺少一個值 - 它會顯示爲輸出中最後一個排序的項目,當我認爲它應該顯示爲空值時。我可以使用我最初笨重的方法的變體得到我想要的答案,但無法弄清楚如何在您的框架內完成。 – AJG519

+0

當值爲null時,使用'np.where'將null替換爲index,並且使用'np.argsort'代替pandas.Series.argsort會更好:'d.apply(lambda x:x.index .where(x.notnull(),np.nan)[x.values.argsort()])' – Psidom

2

與格式

d.apply(pd.Series.rank).stack().reset_index(0, name='x') \ 
    .set_index('x', append=True).squeeze() \ 
    .unstack(0).rename_axis(None).rename(index=int) 

    2015 2016 
1 OR NV 
2 NV WA 
3 CA OR 
4 WA CA 

或者更好的討厭量的numpy

a = d.values.argsort(0) 

pd.DataFrame(d.index.values[a], range(1, len(d) + 1), d.columns) 

    2015 2016 
1 OR NV 
2 NV WA 
3 CA OR 
4 WA CA 
相關問題