Saya memiliki sesuatu seperti kerangka data berikut yang diindeks oleh negara bagian dan tahun:

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

Saya ingin kerangka data baru di mana indeks adalah peringkat setiap negara bagian untuk tahun itu, dan nilainya adalah negara bagian dalam urutan peringkatnya.

Saya bisa mendapatkan output itu sebagai berikut:

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

Apakah ada cara yang lebih bersih untuk mendapatkan hasil ini?

0
AJG519 17 Maret 2017, 21:20

2 jawaban

Jawaban Terbaik

Anda dapat menggunakan argsort, yang mengembalikan indeks untuk mengurutkan setiap kolom, menerapkannya ke indeks memberikan indeks peringkat dalam urutan menaik:

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

enter image description here

Anda dapat memanggil reset_index(drop=True) jika Anda tidak ingin menyimpan indeks asli pada bingkai data.

3
Psidom 17 Maret 2017, 18:31

Dengan jumlah pemformatan yang menjengkelkan

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

Atau lebih baik dengan 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
2
piRSquared 17 Maret 2017, 18:43