2016-04-01 15 views
5

ho questo frame di dati:Rimodellare frame di dati panda in tante colonne quanti sono i Ripetendo le righe

>> df = pd.DataFrame({'Place' : ['A', 'A', 'B', 'B', 'C', 'C'], 'Var' : ['All', 'French', 'All', 'German', 'All', 'Spanish'], 'Values' : [250, 30, 120, 12, 200, 112]}) 

>> df 
    Place Values  Var 
0  A  250  All 
1  A  30 French 
2  B  120  All 
3  B  12 German 
4  C  200  All 
5  C  112 Spanish 

Esso ha un modello di ripetizione di due righe per ogni Place. Voglio rimodellarlo in modo che sia una riga per Place e la colonna Var diventi due colonne, una per "Tutto" e una per l'altro valore.

Come così:

Place All Language Value 
    A 250  French  30 
    B 120  German  12 
    C 200  Spanish 112 

Una tabella pivot farebbe una colonna per ogni valore unico, e io non voglio questo.

Qual è il metodo di rimodellamento per questo?

risposta

3

Poiché i dati vengono visualizzati in uno schema alternato, possiamo concettualizzare la trasformazione in 2 passaggi.

Fase 1:

Go da

a,a,a 
b,b,b 

Per

a,a,a,b,b,b 

Fase 2: goccia colonne ridondanti.

La seguente soluzione applica reshape allo values di DataFrame; gli argomenti da rimodellare sono (-1, df.shape[1] * 2), che dice 'dammi un frame che ha il doppio delle colonne e il numero di righe che puoi gestire.

Quindi, ho cablato gli indici delle colonne per il filtro: [0, 1, 4, 5] in base al layout dei dati. L'array numpy risultante ha 4 colonne, quindi lo passiamo in un costruttore DataFrame insieme ai nomi di colonna corretti.

È una soluzione illeggibile che dipende dal layout df e produce colonne nell'ordine errato;

import pandas as pd 

df = pd.DataFrame({'Place' : ['A', 'A', 'B', 'B', 'C', 'C'], 'Var' : ['All', 'French', 'All', 'German', 'All', 'Spanish'], 'Values' : [250, 30, 120, 12, 200, 112]}) 

df = pd.DataFrame(df.values.reshape(-1, df.shape[1] * 2)[:,[0,1,4,5]], 
    columns = ['Place', 'All', 'Value', 'Language']) 
+1

Questo funziona! Ma non capisco come. Ti dispiacerebbe spiegare il tuo processo? – robroc

+1

Vedo il tuo punto. Ho aggiunto la spiegazione nella modifica. –

+0

Grazie per questo. Quindi -1 come argomento per 'numpy.reshape' assicura che la dimensione sia mantenuta indipendentemente dall'argomento? – robroc

2

Un approccio diverso:

df = pd.DataFrame({'Place' : ['A', 'A', 'B', 'B', 'C', 'C'], 'Var' : ['All', 'French', 'All', 'German', 'All', 'Spanish'], 'Values' : [250, 30, 120, 12, 200, 112]}) 

df1 = df.set_index('Place').pivot(columns='Var') 

df1.columns = df1.columns.droplevel() 

df1 = df1.set_index('All', append=True).stack().reset_index() 

print(df1) 

uscita:

Place All  Var  0 
0  A 250.0 French 30.0 
1  B 120.0 German 12.0 
2  C 200.0 Spanish 112.0 
+0

Soluzione davvero interessante. L'uso di 'droplevel' e' stack' è intelligente. – robroc

Problemi correlati