2013-12-12 40 views
5

Esiste una funzione panda per trasformare questi dati in modo che mostri le colonne come a, b, c, d, e o qualsiasi cosa si trovi all'interno del campo dati e le righe contano quante lettere ci sono.Transforming Pandas Dataframe

import pandas as pd 

trans = pd.read_table('output.txt', header=None, index_col=0) 

print trans 
>>> 
     1 2 3 4 
0      
11  a b c NaN 
666  a d e NaN 
10101 b c d NaN 
1010 a b c d 
414147 b c NaN NaN 
10101 a b d NaN 
1242 d e NaN NaN 
101  a b c d 
411  c d e NaN 
444  a b c NaN 

invece voglio l'uscita per essere come questo:

 a b c  d e 
0      
11  1 1 1 NaN NaN 
666  1 NaN NaN 1 1 

La funzione .STACK() ottiene quasi fatto, ma nel formato sbagliato.

risposta

5

Si potrebbe anche usare Pandas get_dummies()

pd.get_dummies(df.unstack().dropna()).groupby(level=1).sum() 

risultati in:

 a b c d e 
0      
11  1 1 1 0 0 
666  1 0 0 1 1 
10101 0 1 1 1 0 
1010 1 1 1 1 0 
414147 0 1 1 0 0 
10101 1 1 0 1 0 
1242 0 0 0 1 1 
101  1 1 1 1 0 
411  0 0 1 1 1 
444  1 1 1 0 0 

È possibile sostituire gli zeri con Nan nel vuoi a.

È un po 'oscuro in una riga. df.unstack().dropna() sostanzialmente appiattisce il tuo DataFrame a una serie e rilascia al NaN. Il numero get_dummies fornisce una tabella di tutte le occorrenze delle lettere, ma per ogni livello nel dataFrame di unstack. Il raggruppamento e la somma combinano quindi l'indice con la forma originale.

+0

Bella. Molto meglio del mio tentativo (ora cancellato) di far funzionare get_dummies su un DataFrame. Mi piace molto l'idioma '' unstack(). Dropna() ''. –

+0

Ho notato che avresti potuto lasciarlo, nessun danno nell'avere alcune opzioni. Sono ancora d'accordo con il tuo precedente commento che è meno bello (e leggibile) della soluzione 'pivot' da Roman. Il concetto di pivot è anche più noto, quindi ... 'get_dummies'. :) –

2

Qualcosa di simile potrebbe essere:

>>> st = pd.DataFrame(trans.stack()).reset_index(level=0) 
>>> st.columns = ['i','c'] 
>>> st.pivot_table(rows='i', cols='c', aggfunc=len) 
c  a b c d e 
i       
11  1 1 1 NaN NaN 
101  1 1 1 1 NaN 
411 NaN NaN 1 1 1 
444  1 1 1 NaN NaN 
666  1 NaN NaN 1 1 
1010  1 1 1 1 NaN 
1242 NaN NaN NaN 1 1 
10101 1 2 1 2 NaN 
414147 NaN 1 1 NaN NaN 
+0

close ma .reset_index (level = 0) restituisce un errore ValueError ('impossibile inserire% s, esiste già'% item) – user3084006

+1

quale versione di panda usi? –

+0

Sto usando la versione di sviluppo versione 0.13 dal 04-Dec-2013 – user3084006