2016-09-21 1 views
0

betrachten die Datenrahmen dfTwist Datenrahmen von Rang

np.random.seed([3,1415]) 
df = pd.DataFrame(np.random.rand(4, 5), columns=list('ABCDE')) 
df 

enter image description here


ich einen Datenrahmen wollen, wo die Spalten Reihen und jede Reihe ist ['A', 'B', 'C', 'D', 'E'] in Rangordnung.

stuft

df.rank(1).astype(int) 

enter image description here


erwarteten Ergebnisse

enter image description here

Antwort

3

Hier ist eine Art und Weise:

In [90]: df 
Out[90]: 
      A   B   C   D   E 
0 0.444939 0.407554 0.460148 0.465239 0.462691 
1 0.016545 0.850445 0.817744 0.777962 0.757983 
2 0.934829 0.831104 0.879891 0.926879 0.721535 
3 0.117642 0.145906 0.199844 0.437564 0.100702 

In [91]: df2 = df.apply(lambda row: df.columns[np.argsort(row)], axis=1) 

In [92]: df2 
Out[92]: 
    A B C D E 
0 B A C E D 
1 A E D C B 
2 E B C D A 
3 E A B C D 

Die neue Datenrahmen hat die gleiche Spaltenindex als df, aber das behoben werden kann:

In [93]: df2.columns = range(1, 1 + df2.shape[1]) 

In [94]: df2 
Out[94]: 
    1 2 3 4 5 
0 B A C E D 
1 A E D C B 
2 E B C D A 
3 E A B C D 

Hier ist eine andere Art und Weise ist. Dieser konvertiert den DataFrame in ein numpliges Array, wendet argsort auf Achse 1 an, verwendet das zum Indexieren df.columns und setzt das Ergebnis wieder in einen DataFrame.

In [110]: pd.DataFrame(df.columns[np.array(df).argsort(axis=1)], columns=range(1, 1 + df.shape[1])) 
Out[110]: 
    1 2 3 4 5 
0 B A C E D 
1 A E D C B 
2 E B C D A 
3 E A B C D 
+0

Ich habe 3 Lösungen. Du hast einen von ihnen getroffen. – piRSquared

+0

Das zweite war meine beste Antwort. Beeindruckende Arbeit. Meine letzte war zu stapeln, Index zurückzusetzen und dann zu schwenken. – piRSquared

0

Verwenden stack, reset_index und pivot

df.rank(1).astype(int).stack().reset_index() \ 
    .pivot('level_0', 0, 'level_1').rename_axis(None) 

enter image description here


TIMING

enter image description here

1

Hier ist ein anderer Weg.

In [5]: df1 = df.rank(1).astype(int) 

In [6]: df3 = df1.replace({rank: name for rank, name in enumerate(df1.columns, 1)}) 

In [7]: df3.columns = range(1, 1 + df3.shape[1]) 

In [8]: df3 
Out[8]: 
    1 2 3 4 5 
0 B A C E D 
1 A E D C B 
2 E B C D A 
3 B C D E A 

Noch ein anderer Weg.

In [6]: ranks = df.rank(axis=1).astype(int)-1 
In [7]: new_values = df.columns.values.take(ranks) 

In [8]: pd.DataFrame(new_values) 
Out[8]: 
    0 1 2 3 4 
0 B A C E D 
1 A E D C B 
2 E B C D A 
3 B C D E A 
+0

Das ist ein großartiger. – piRSquared

+0

@piRSquared letzte Zeile des Datenrahmens hat unterschiedliche Werte in Warren Weckessers Antwort. Der Rest der Zeilen hat jedoch den gleichen Wert wie erwartet. – Hariprasad