2016-04-01 13 views
5

mam tej ramki danych:Zmiana kształtu ramki danych pandy na tyle kolumn, ile jest powtarzanie wierszy

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

Ma powtarzający się wzór z dwoma rzędami na każdą Place. Chcę przekształcić go tak, aby był jeden wiersz na kolumnę Place, a kolumna Var stała się dwiema kolumnami, jedną dla "Wszystkie" i jedną dla drugiej wartości.

tak:

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

Stół obrotowy uniemożliwiłoby kolumnę dla każdej unikatowej wartości, a nie chcę tego.

Jaka jest metoda zmiany kształtu?

Odpowiedz

3

Ponieważ dane pojawiają się na przemian, możemy konceptualizować transformację w 2 krokach.

Krok 1:

Go z

a,a,a 
b,b,b 

Aby

a,a,a,b,b,b 

Krok 2: Usuń nadmiarowe kolumn.

Następujące rozwiązanie ma zastosowanie reshape do values obiektu DataFrame; Argumenty przemodelowania to (-1, df.shape[1] * 2), które mówią "daj mi ramkę, która ma dwa razy więcej kolumn i tyle wierszy, ile możesz zarządzać.

Następnie na stałe włączyłem indeksy kolumn dla filtra: [0, 1, 4, 5] w oparciu o twój układ danych. Wynikowa tablica numpy ma 4 kolumny, więc przekazujemy ją do konstruktora DataFrame wraz z poprawnymi nazwami kolumn.

Jest to nieczytelne rozwiązanie, które zależy od układu df i tworzy kolumny w niewłaściwej kolejności;

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

To działa! Ale nie do końca rozumiem, jak. Czy mógłbyś wyjaśnić swój proces? – robroc

+1

Widzę twój punkt widzenia. Dodałem wyjaśnienie w edycji. –

+0

Dzięki za to. Więc -1 jako argument dla 'numpy.reshape' zapewnia zachowanie wymiaru bez względu na to, jaki jest inny argument? – robroc

2

Inne podejście:

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) 

wyjściowa:

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

Naprawdę interesujące rozwiązanie. Użycie 'droplevel' i' stack' jest sprytne. – robroc

Powiązane problemy