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!

user1357015
quelle

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'>
DSM
quelle
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, :]
Alexander
quelle
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.

Tauseef Malik
quelle
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

Cleveres Omo
quelle
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

user12230680
quelle
5
Willkommen bei Stack Overflow! Wie beantwortet dies die Frage? Ihr Code gibt keine Serie zurück, wie die Frage stellt
Gricey