Python-Pandas: Behalten Sie die ausgewählte Spalte als DataFrame anstelle von Series bei


92

Wenn eine einzelne Spalte aus einer pandas Datenrahmen Auswählen (sagen wir df.iloc[:, 0], df['A']oder df.A, etc.), wird der resultierende Vektor automatisch auf eine Serie umgewandelt anstelle eines Datenrahmens mit einer Spalte. Ich schreibe jedoch einige Funktionen, die einen DataFrame als Eingabeargument verwenden. Daher bevorzuge ich den Umgang mit einspaltigem DataFrame anstelle von Series, damit die Funktion davon ausgehen kann, dass auf df.columns zugegriffen werden kann. Im Moment muss ich die Serie explizit in einen DataFrame konvertieren, indem ich so etwas verwende pd.DataFrame(df.iloc[:, 0]). Dies scheint nicht die sauberste Methode zu sein. Gibt es eine elegantere Möglichkeit, einen DataFrame direkt zu indizieren, sodass das Ergebnis ein einspaltiger DataFrame anstelle von Series ist?


6
df.iloc [:, [0]] oder df [['A']]; df.A wird jedoch nur eine Serie zurückgeben
Jeff

Antworten:


99

Wie @Jeff erwähnt, gibt es einige Möglichkeiten, dies zu tun, aber ich empfehle, loc / iloc zu verwenden, um expliziter zu sein (und Fehler frühzeitig auszulösen, wenn Sie etwas Zweideutiges versuchen):

In [10]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B'])

In [11]: df
Out[11]:
   A  B
0  1  2
1  3  4

In [12]: df[['A']]

In [13]: df[[0]]

In [14]: df.loc[:, ['A']]

In [15]: df.iloc[:, [0]]

Out[12-15]:  # they all return the same thing:
   A
0  1
1  3

Die beiden letztgenannten Optionen beseitigen Mehrdeutigkeiten bei ganzzahligen Spaltennamen (genau, warum loc / iloc erstellt wurden). Zum Beispiel:

In [16]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 0])

In [17]: df
Out[17]:
   A  0
0  1  2
1  3  4

In [18]: df[[0]]  # ambiguous
Out[18]:
   A
0  1
1  3

2
Tut mir leid, dass ich Sie störe, aber nur eine kurze Frage dazu. Ich sehe, wie das Extra []das Ergebnis zu einem DataFramestatt zu einem macht Series, aber wo in den Pandas-Dokumenten wird diese Art der Indizierungssyntax diskutiert? Ich versuche nur, den "offiziellen" Namen für diese Indizierungstechnik zu finden, damit ich sie wirklich verstehe. Danke!
sparc_spread

3
@sparc_spread pandas.pydata.org/pandas-docs/stable/indexing.html#basics "Sie können eine Liste von Spalten an [] übergeben, um Spalten in dieser Reihenfolge auszuwählen." Ich bin mir nicht sicher, ob dies einen Namen hat!
Andy Hayden

Ja, es sieht so aus, als hätte es keine - aber ich werde es von jetzt an weiter benutzen. Erstaunlich, wie viel Material sowohl in der API als auch in den Dokumenten vergraben ist. Danke!
sparc_spread

Diese Unterscheidung war für mich nützlich, da ich manchmal einen einspaltigen DataFrame möchte, damit ich DataFrame-Methoden für die Daten verwenden kann, die in Series nicht verfügbar waren. (ISTR die Plotmethode verhielt sich anders). Es war eine Offenbarung für mich, als mir klar wurde, dass ich eine Einzelelementliste verwenden kann!
RufusVS

4

Wie Andy Hayden empfiehlt, ist die Verwendung von .iloc / .loc zum Indizieren von (einspaltigen) Datenrahmen der richtige Weg. Ein weiterer zu beachtender Punkt ist das Ausdrücken der Indexpositionen. Verwenden Sie eine aufgelistete Indexbezeichnung / -position, während Sie die Argumentwerte angeben, die als Datenrahmen indiziert werden sollen. Andernfalls wird eine 'pandas.core.series.Series' zurückgegeben.

Eingang:

    A_1 = train_data.loc[:,'Fraudster']
    print('A_1 is of type', type(A_1))
    A_2 = train_data.loc[:, ['Fraudster']]
    print('A_2 is of type', type(A_2))
    A_3 = train_data.iloc[:,12]
    print('A_3 is of type', type(A_3))
    A_4 = train_data.iloc[:,[12]]
    print('A_4 is of type', type(A_4))

Ausgabe:

    A_1 is of type <class 'pandas.core.series.Series'>
    A_2 is of type <class 'pandas.core.frame.DataFrame'>
    A_3 is of type <class 'pandas.core.series.Series'>
    A_4 is of type <class 'pandas.core.frame.DataFrame'>

1

Sie können verwenden df.iloc[:, 0:1], in diesem Fall ist der resultierende Vektor eine DataFrameund keine Reihe.

Wie du siehst:

Geben Sie hier die Bildbeschreibung ein


1

Diese drei Ansätze wurden erwähnt:

pd.DataFrame(df.loc[:, 'A'])  # Approach of the original post
df.loc[:,[['A']]              # Approach 2 (note: use iloc for positional indexing)
df[['A']]                     # Approach 3

pd.Series.to_frame () ist ein anderer Ansatz.

Da es sich um eine Methode handelt, kann sie in Situationen verwendet werden, in denen der zweite und dritte Ansatz oben nicht zutreffen. Dies ist insbesondere dann hilfreich, wenn Sie eine Methode auf eine Spalte in Ihrem Datenrahmen anwenden und die Ausgabe in einen Datenrahmen anstelle einer Reihe konvertieren möchten. In einem Jupyter-Notizbuch hat eine Serie beispielsweise keine schöne Ausgabe, aber ein Datenrahmen.

# Basic use case: 
df['A'].to_frame()

# Use case 2 (this will give you pretty output in a Jupyter Notebook): 
df['A'].describe().to_frame()

# Use case 3: 
df['A'].str.strip().to_frame()

# Use case 4: 
def some_function(num): 
    ...

df['A'].apply(some_function).to_frame()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.