Converti frame di dati panda in serie


98

Sono un po 'nuovo per i panda. Ho un frame di dati panda che è 1 riga per 23 colonne.

Voglio convertirlo in una serie? Mi chiedo qual è il modo più pitonico per farlo?

Ho provato pd.Series(myResults)ma si lamentaValueError: cannot copy sequence with size 23 to array axis with dimension 1 . Non è abbastanza intelligente da rendersi conto che è ancora un "vettore" in termini matematici.

Grazie!

Risposte:


64

Non è abbastanza intelligente per rendersi conto che è ancora un "vettore" in termini matematici.

Dì piuttosto che è abbastanza intelligente da riconoscere una differenza di dimensionalità. :-)

Penso che la cosa più semplice che puoi fare sia selezionare quella riga in posizione usando iloc, che ti dà una serie con le colonne come nuovo indice e i valori come valori:

>>> 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'>

2
Oppure, in un altro modo:df.T
ako

14
@ako: df.Tnon produce una serie, però, solo un DataFrame trasposto.
DSM

@DSM. È vero, df.T.iloc [0]
Antonio Andrés

L'unico problema con l'utilizzo df.ilocè che se hai un df vuoto, questo solleverà un file IndexError. Per evitare ciò, dopo aver trasposto il tuo df, usa il df.squeezemetodo. Rif. a pandas.pydata.org/pandas-docs/stable/reference/api/…
Nicolas Fonteyne,

60

Puoi trasporre il dataframe a riga singola (che risulta comunque in un dataframe) e quindi comprimere i risultati in una serie (l'inverso di 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

Nota: per accogliere il punto sollevato da @IanS (anche se non è nella domanda dell'OP), verifica la dimensione del dataframe. dfSuppongo che sia un dataframe, ma i casi limite sono un dataframe vuoto, un dataframe di forma (1, 1) e un dataframe con più di una riga, nel qual caso l'uso dovrebbe implementare la funzionalità desiderata.

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

Questo può anche essere semplificato sulla falsariga della risposta fornita da @themachinist.

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

11
Nota che ho riscontrato un piccolo problema nell'utilizzo di squeeze. Per un dataframe di forma (1, 1)restituirà, non una serie di lunghezza 1, ma uno scalare numpy. Ciò ha portato a un bug difficile da individuare quando si utilizza squeezesu oggetti di lunghezza sconosciuta (ad esempio con groupby).
IanS

2
"Grazie! Df.squeeze () ha funzionato quando df.iloc [:, 0] e df.ix [:, 0] hanno entrambi prodotto troppi errori negli indici"
Afflatus

3
E perché è l'inverso di to_frameno to_serieso pd.Series(df)...?
jhin

4
Non è necessario.T
elgehelge

1
@IanS passa l'argomento df.squeeze(axis=0)odf.squeeze(axis=1) (a seconda dell'asse che vuoi conservare) per evitarlo
Nicolas Fonteyne,


4

Un altro modo -

Supponiamo che myResult sia il dataFrame che contiene i tuoi dati sotto forma di 1 colonna e 23 righe

// 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 modo simile, puoi ottenere serie da Dataframe con più colonne.


3

Puoi anche usare stack ()

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

Dopo aver eseguito df, quindi eseguire:

df.stack()

Ottieni il tuo dataframe 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)

Ciò fornisce un dataframe con indice come nome di colonna di dati e tutti i dati sono presenti nella colonna "valori"


5
Benvenuto in Stack Overflow! Come risponde questo alla domanda? Il tuo codice non restituisce una serie come la domanda chiede
Gricey
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.