Konvertieren Sie den Pandas-Datenrahmen in Serien


89

Ich bin etwas neu in Pandas. Ich habe einen Pandas-Datenrahmen, der 1 Zeile mal 23 Spalten umfasst.

Ich möchte dies in eine Serie umwandeln? Ich frage mich, was der pythonischste Weg ist, dies zu tun.

Ich habe es versucht, pd.Series(myResults)aber es beschwert sich ValueError: cannot copy sequence with size 23 to array axis with dimension 1. Es ist nicht klug genug zu erkennen, dass es in mathematischer Hinsicht immer noch ein "Vektor" ist.

Vielen Dank!

Antworten:


61

Es ist nicht klug genug zu erkennen, dass es in mathematischer Hinsicht immer noch ein "Vektor" ist.

Sagen Sie lieber, dass es klug genug ist, einen Unterschied in der Dimensionalität zu erkennen. :-)

Ich denke, das Einfachste, was Sie tun können, ist, diese Zeile positionell auszuwählen iloc, wodurch Sie eine Reihe mit den Spalten als neuem Index und den Werten als Werten erhalten:

>>> df = pd.DataFrame([list(range(5))], columns=["a{}".format(i) for i in range(5)])
>>> df
   a0  a1  a2  a3  a4
0   0   1   2   3   4
>>> df.iloc[0]
a0    0
a1    1
a2    2
a3    3
a4    4
Name: 0, dtype: int64
>>> type(_)
<class 'pandas.core.series.Series'>

1
Oder df.T
anders

13
@ako: produziert df.Tjedoch keine Serie, sondern nur einen transponierten DataFrame.
DSM

57

Sie können die einreihige Datenrahmen umzusetzen (die in einem Datenrahmen ergibt sich immer noch) und dann drücken Sie die Ergebnisse in einer Reihe (die Inverse to_frame).

df = pd.DataFrame([list(range(5))], columns=["a{}".format(i) for i in range(5)])

>>> df.T.squeeze()  # Or more simply, df.squeeze() for a single row dataframe.
a0    0
a1    1
a2    2
a3    3
a4    4
Name: 0, dtype: int64

Hinweis: Um den von @IanS angesprochenen Punkt zu berücksichtigen (auch wenn dies nicht in der Frage des OP steht), testen Sie die Größe des Datenrahmens. Ich dfgehe davon aus, dass dies ein Datenrahmen ist, aber die Randfälle sind ein leerer Datenrahmen, ein Datenrahmen mit Form (1, 1) und ein Datenrahmen mit mehr als einer Zeile. In diesem Fall sollte die Verwendung ihre gewünschte Funktionalität implementieren.

if df.empty:
    # Empty dataframe, so convert to empty Series.
    result = pd.Series()
elif df.shape == (1, 1)
    # DataFrame with one value, so convert to series with appropriate index.
    result = pd.Series(df.iat[0, 0], index=df.columns)
elif len(df) == 1:
    # Convert to series per OP's question.
    result = df.T.squeeze()
else:
    # Dataframe with multiple rows.  Implement desired behavior.
    pass

Dies kann auch im Sinne der Antwort von @themachinist vereinfacht werden.

if len(df) > 1:
    # Dataframe with multiple rows.  Implement desired behavior.
    pass
else:
    result = pd.Series() if df.empty else df.iloc[0, :]

10
Beachten Sie, dass ich bei der Verwendung auf ein kleines Problem gestoßen bin squeeze. Für einen Datenrahmen mit Form (1, 1)wird nicht eine Reihe von Längen 1, sondern ein numpy-Skalar zurückgegeben. Dies führte zu einem schwer zu fassenden Fehler bei der Verwendung squeezevon Objekten unbekannter Länge (z groupby. B. mit ).
IanS

2
"Danke! Df.squeeze () hat funktioniert, als df.iloc [:, 0] & df.ix [:, 0] beide zu viele Indexfehler erzeugt haben"
Afflatus

3
Und warum ist das Gegenteil von to_framenicht to_seriesoder pd.Series(df)...?
Jhin

4
Sie brauchen nicht.T
Elgehelge


4

Ein anderer Weg -

Angenommen, myResult ist der Datenrahmen, der Ihre Daten in Form von 1 Spalte und 23 Zeilen enthält

// label your columns by passing a list of names
myResult.columns = ['firstCol']

// fetch the column in this way, which will return you a series
myResult = myResult['firstCol']

print(type(myResult))

In ähnlicher Weise können Sie Serien von Dataframe mit mehreren Spalten abrufen.


2

Sie können auch stack () verwenden

df= DataFrame([list(range(5))], columns = [“a{}”.format(I) for I in range(5)])

Nachdem Sie df ausgeführt haben, führen Sie Folgendes aus:

df.stack()

Sie erhalten Ihren Datenrahmen in Serie


0
data = pd.DataFrame({"a":[1,2,3,34],"b":[5,6,7,8]})
new_data = pd.melt(data)
new_data.set_index("variable", inplace=True)

Dies ergibt einen Datenrahmen mit Index als Spaltennamen der Daten und alle Daten sind in der Spalte "Werte" vorhanden


5
Willkommen bei Stack Overflow! Wie beantwortet dies die Frage? Ihr Code gibt keine Serie zurück, wie die Frage stellt
Gricey
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.