Jestem trochę nowy w pandach. Mam ramkę danych pandy, która ma 1 wiersz na 23 kolumny.
Chcę przekształcić to w serię? Zastanawiam się, jaki jest najbardziej pytoniczny sposób na zrobienie tego?
Próbowałem, pd.Series(myResults)
ale narzeka ValueError: cannot copy sequence with size 23 to array axis with dimension 1
. Nie jest wystarczająco inteligentne, aby zdać sobie sprawę, że w kategoriach matematycznych nadal jest to „wektor”.
Dzięki!
df.T
df.T
nie tworzy jednak serii, tylko transponowaną ramkę DataFrame.df.iloc
jest to, że jeśli masz pusty df, spowoduje to podniesienieIndexError
. Aby tego uniknąć, po transpozycji df użyjdf.squeeze
metody. Nr ref. to pandas.pydata.org/pandas-docs/stable/reference/api/…Można przetransponować jednorzędową ramkę danych (co nadal skutkuje ramką danych), a następnie ścisnąć wyniki w serię (odwrotność
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
Uwaga: Aby uwzględnić kwestię podniesioną przez @IanS (nawet jeśli nie ma jej w pytaniu OP), przetestuj rozmiar ramki danych. Zakładam, że
df
jest to ramka danych, ale przypadki brzegowe to pusta ramka danych, ramka danych o kształcie (1, 1) i ramka danych z więcej niż jednym wierszem, w którym to przypadku użycie powinno zaimplementować ich pożądaną funkcjonalność.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
Można to również uprościć, korzystając z odpowiedzi udzielonej przez @themachinist.
if len(df) > 1: # Dataframe with multiple rows. Implement desired behavior. pass else: result = pd.Series() if df.empty else df.iloc[0, :]
źródło
squeeze
. W przypadku ramki danych o kształcie(1, 1)
zwróci nie serię o długości 1, ale numpy skalar. Doprowadziło to do trudnego do wykrycia błędu podczas używaniasqueeze
na obiektach o nieznanej długości (np. Zgroupby
).to_frame
nieto_series
lubpd.Series(df)
...?.T
df.squeeze(axis=0)
lubdf.squeeze(axis=1)
(w zależności od osi, którą chcesz zachować), aby tego uniknąćMożesz pobrać serię, przecinając ramkę danych za pomocą jednej z następujących dwóch metod:
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.iloc.html http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.loc.html
import pandas as pd import numpy as np df = pd.DataFrame(data=np.random.randn(1,8)) series1=df.iloc[0,:] type(series1) pandas.core.series.Series
źródło
Inny sposób -
Załóżmy, że myResult to dataFrame, która zawiera Twoje dane w postaci 1 kolumny i 23 wierszy
// 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))
W podobny sposób możesz uzyskać serie z Dataframe z wieloma kolumnami.
źródło
Możesz także użyć stack ()
df= DataFrame([list(range(5))], columns = [“a{}”.format(I) for I in range(5)])
Po uruchomieniu df uruchom:
Otrzymujesz swoją ramkę danych w serii
źródło
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)
Daje to ramkę danych z indeksem jako nazwą kolumny danych, a wszystkie dane są obecne w kolumnie „wartości”
źródło