Sono curioso del comportamento dei panda groupby-apply quando la funzione apply restituisce una serie.pandas groupby-applica il comportamento, restituendo una serie (tipo di output incoerente)
Quando le serie sono di lunghezza diversa, restituisce una serie con più indici.
In [1]: import pandas as pd
In [2]: df1=pd.DataFrame({'state':list("AABBB"),
...: 'city':list("vwxyz")})
In [3]: df1
Out[3]:
city state
0 v A
1 w A
2 x B
3 y B
4 z B
In [4]: def f(x):
...: return pd.Series(x['city'].values,index=range(len(x)))
...:
In [5]: df1.groupby('state').apply(f)
Out[5]:
state
A 0 v
1 w
B 0 x
1 y
2 z
dtype: object
Restituisce un oggetto Series
.
Tuttavia, se ogni serie ha la stessa lunghezza, viene ruotata su DataFrame
.
In [6]: df2=pd.DataFrame({'state':list("AAABBB"),
...: 'city':list("uvwxyz")})
In [7]: df2
Out[7]:
city state
0 u A
1 v A
2 w A
3 x B
4 y B
5 z B
In [8]: df2.groupby('state').apply(f)
Out[8]:
0 1 2
state
A u v w
B x y z
È davvero questo il comportamento previsto? Abbiamo intenzione di verificare il tipo di reso se usiamo applicare in questo modo? O c'è un'opzione in apply
che non sto apprezzando?
Nel caso in cui sei curioso, nel mio caso di utilizzo effettivo, la serie restituita avrà la stessa lunghezza della lunghezza del gruppo. Sembra un caso ideale per transform
tranne per il fatto che ho trovato che apply
con la restituzione di una serie è in realtà un ordine di grandezza più veloce su un set di dati di grandi dimensioni. Questo può essere un altro argomento.
Edit: Liberamente ispirato risposta del Parfait, si può certamente fare questo:
X=df.groupby('state').apply(f)
if not isinstance(X,pd.Series):
X=X.stack()
X
Che darà lo stesso tipo di uscita sia per df=df1
o df=df2
. Suppongo che sto solo chiedendo se questo è davvero il modo normale o preferito per gestire questo.
Capisco _quando questo accade, ma sembra ancora strano. Se non sto lavorando in modo interattivo, sembra che devo controllare il tipo di dati del risultato per procedere. Chiamare '.reset_index()' o '.unstack()' avrà comunque risultati completamente diversi a seconda che iniziassi con i dati 'df1' o' df2'. –
Un buon punto sull'utilizzo di 'stack' e' unstack' è il modo migliore per forzare tra i due tipi di output, grazie. Ho modificato la domanda per includerla. –
Come detto 'groupby(). Apply()' non garantisce il ritorno di un frame di dati in quanto dipende dagli input e dalle operazioni e quindi può generare strutture diverse. Considerare una funzione/classe definita dall'utente per gestire i vari output. – Parfait