Ich habe eine Liste von Werten mit dem gewünschten Spaltenindex für jede Zeile eines Pandas DataFrame. Wie ordne ich diese Liste der Spaltenbeschriftungen jeder Zeile des DataFrame zu?

Wenn ich den DataFrame einfach anhand der Liste indiziere, wird die gesamte Liste wie folgt auf jede Zeile angewendet.

In [10]: df = pd.DataFrame(np.random.randn(5,2), columns=list('AB'))

In [11]: df
Out[11]: 
          A         B
0 -0.082240 -2.182937
1  0.380396  0.084844
2  0.432390  1.519970
3 -0.493662  0.600178
4  0.274230  0.132885

In[12]: selection = list('ABBAA')

In[13]: selection
Out[13]: ['A', 'B', 'B', 'A', 'A']

In[14]: df[selection]
Out[14]:
          A         B         B         A         A
0 -0.082240 -2.182937 -2.182937 -0.082240 -0.082240
1  0.380396  0.084844  0.084844  0.380396  0.380396  
2  0.432390  1.519970  1.519970  0.432390  0.432390
3 -0.493662  0.600178  0.600178 -0.493662 -0.493662
4  0.274230  0.132885  0.132885  0.274230  0.274230

Jedes Element in der Auswahlliste gibt die Spalte an, die aus der entsprechenden Zeile im DataFrame ausgewählt werden soll. In diesem Beispiel möchte ich die Spalte A aus der ersten Zeile, B aus der zweiten und dritten Zeile und dann A aus der vierten und fünften Zeile. Es stellt sich heraus, dass dies die Diagonale des obigen Ergebnisses ist. Mein tatsächlicher DataFrame ist viel größer und ich halte es nicht für sinnvoll, das obige Ergebnis nur zu erstellen, um die Diagonale auszuwählen.

Ich kann dies sicherlich erreichen, indem ich die Zeilen durchlaufe, aber ich gehe davon aus, dass Pandas eine integrierte Methode hat, um dies zu tun. Ich suche nach der Methode, um das folgende Ergebnis zu erhalten.

In[15]: df <do something> selection
Out[15]:
0 -0.082240
1  0.084844
2  1.519970
3 -0.493662
4  0.274230

2
Steven C. Howell 17 Jän. 2019 im 23:02

4 Antworten

Beste Antwort

Sie schneiden den Datenrahmen zweimal auf, wenn Sie zuerst Spalten basierend auf der Auswahl auswählen und dann die diagonalen Werte erhalten. Sie können stattdessen Lookup verwenden, das eine zurückgibt Array der Werte, die jedem Paar (Zeile, Spalte) entsprechen.

df.lookup(df.index, selection)

array([-0.08224 ,  0.084844,  1.51997 , -0.493662,  0.27423 ])

Wenn Sie die Daten in Form von Pandas-Serien wünschen,

pd.Series(df.lookup(df.index, selection))

0   -0.082240
1    0.084844
2    1.519970
3   -0.493662
4    0.274230
4
Vaishali 17 Jän. 2019 im 20:51

Verwenden Sie reindex:

df.reindex(selection, axis=1)

Ausgabe:

          A         B         B         A         A
0  0.065447 -1.890299 -1.890299  0.065447  0.065447
1  0.389780  0.301049  0.301049  0.389780  0.389780
2  0.484159 -1.311432 -1.311432  0.484159  0.484159
3 -0.209745 -2.233050 -2.233050 -0.209745 -0.209745
4 -0.093495 -1.527827 -1.527827 -0.093495 -0.093495

Verwenden Sie dann np.eye und mask

df.reindex(selection, axis=1).mask(np.eye(5) == 0).stack()

Ausgabe:

0  A    0.065447
1  B    0.301049
2  B   -1.311432
3  A   -0.209745
4  A   -0.093495
dtype: float64
2
Scott Boston 17 Jän. 2019 im 20:08

IIUC, versuch das mal

df[selection].values.diagonal()

Wenn Sie in Form von Series benötigen, wie Sie bemerkt haben, tun Sie -

pd.Series(df[selection].values.diagonal())
1
meW 17 Jän. 2019 im 20:12

Ich kann nur an die numpy Methode denken

pd.Series(df.values[df.index,df.columns.get_indexer(selection)])
Out[563]: 
0   -0.082240
1    0.084844
2    1.519970
3   -0.493662
4    0.274230
dtype: float64
3
YO and BEN_W 17 Jän. 2019 im 20:14