2015-07-08 38 views
5

Próbuję wykonać transformację ramek danych, której nie mogę rozwiązać. Próbowałem wielu podejść od stackoverflow i dokumentacji pandy: zastosuj, zastosuj (lambda: ...), pivots i joins. Zbyt wiele prób, aby tutaj wymienić, ale nie jestem pewien, które podejście jest najlepsze, a może spróbowałem odpowiedniego podejścia z niewłaściwą składnią.Python - Pandy - Dataframe: Przesunięcie wiersza warunkowego wiersza warunkowego

Zasadniczo posiadam ramkę danych i muszę 1) przesunąć kolumny, 2) liczba kolumn do przesunięcia zmienia się i zależy od zmiennej w ramce danych, 3) utworzyć kolumny na końcu ramki danych tam, gdzie jest to konieczne, aby uwzględnić przesunięcie, oraz 4) umieścić zera w nowo utworzonych odstępach czasu.

df1 = pd.DataFrame({'first' : ['John', 'Mary', 'Larry', 'jerry'], '1' : [5.5, 6.0,10,20], '2' : [100, 200, 300, 400], '3' : [150, 100, 240, 110], 'offset' : ([1,0,2,1])}) 
goal_df = pd.DataFrame({'first' : ['John', 'Mary', 'Larry', 'jerry'], '1' : [0.0, 6.0, 0.0, 0], '2' : [5.5, 200, 0.0, 20], '3' : [100, 100, 10, 400], '4' : [150, 0.0, 300, 110], '5' : [0.0, 0.0, 240, 0.0]}) 

df1 
1   2  3 first  offset 
5.5  100  150 John  1 
6.0  200  100 Mary  0 
10.0  300  240 Larry  2 
20.0  400  110 jerry  1 


goal_df 
1  2 3 4 5 first 
0 5.5 100 150 0 John 
6 200.0 100 0 0 Mary 
0 0.0 10 300 240 Larry 
0 20.0 400 110 0 jerry 

Ten zestaw danych będzie miał c. 500 wierszy i c. 120 kolumn. Wielkość przesunięcia będzie bardzo bliska 0-12. Zastanawiałem się nad tym przy pomocy podstawowych funkcji Pythona, ale odkryłem również, że trudny i czasochłonny program użytkownika pokona ostateczny cel, jakim jest usunięcie niektórych zadań wykonywanych w programie Microsoft Excel.

Bardzo dużo narzekam na to, jak Excel jest gorszy w przypadku dużych zadań takich jak ten, ale wydaje się, że obecna funkcja offset offset() w programie Excel działa w bardzo łatwy sposób, ale z tysiącami formuł, jest bardzo wolny. Sprzedałem moje miejsce pracy na temat korzyści płynących z Pythona w Excelu i jest to moja pierwsza prawdziwa wersja próbna, więc szybkość jest dla mnie bardzo ważna, ponieważ staram się przekonać moich kolegów, że Python może pożerać ten arkusz kalkulacyjny znacznie szybciej niż obecny program Excel. ważenie pliku w rozmiarze pliku 96 MB.

Podszedłem dość blisko funkcji stopu(), a następnie biorąc poprzednie numery kolumn i dodałem do nich przesunięcie. Miałem jednak wiele problemów przy próbie zreformowania ramki danych za pomocą funkcji przestawnej. Bez powodzenia z aplikowaniem lub aplikowaniem (lambda)!

Dzięki za pomoc, jaką każdy może dać!

Odpowiedz

3

To nie jest szczególnie eleganckie ani zwięzłe, ale powinno załatwić sprawę. Uważam, że troszkę łatwiej jest przetasować kolumny w numpy (również powinno być trochę szybciej), więc najpierw konwertuję dane z ramki danych na tablicę.

arr = df1.values[:,:-2] # just the numbers 
offset = df1.values[:,-1]  # just the offsets 
column_pad = 2 
arr2 = np.zeros((arr.shape[0],arr.shape[1]+column_pad)) 

Oto kod klucza, który po prostu przesuwa każdy wiersz o wartość przesunięcia.

for i, j in enumerate(offset): 
    arr2[i,j:3+j] = arr[i] 

array([[ 0. , 5.5, 100. , 150. , 0. ], 
     [ 6. , 200. , 100. , 0. , 0. ], 
     [ 0. , 0. , 10. , 300. , 240. ], 
     [ 0. , 20. , 400. , 110. , 0. ]]) 

Poza tym to tylko odrobina ręcznej pracy, aby dodać miejsce na kolumny i umieścić je we właściwej kolejności.

df2 = df1.copy() 
last_column = 6 
for i in map(str,range(3,last_column)): 
    df2[i] = 0 
df2 = df2[ map(str,range(1,last_column))+['first','offset']] 

Następnie załaduj arr2 do df2.

df2.loc[:,'1':'5'] = arr2 

    1  2 3 4 5 first offset 
0 0 5.5 100 150 0 John  1 
1 6 200.0 100 0 0 Mary  0 
2 0 0.0 10 300 240 Larry  2 
3 0 20.0 400 110 0 jerry  1 
+0

Dzięki za spojrzenie. Próbuję twojego rozwiązania, więc przynajmniej mam coś, co działa. W międzyczasie zamierzam spróbować opracować tę jedną ścieżkę topienia ramki danych i mutowania numerów kolumn (stary numer kolumny + przesunięcie). Jedynym problemem jest to, że kiedy idę do "unmelt" theframeframe, the pivot całkowicie psuje wszystko do góry. – nordicray

+0

@nordicray OK, jeśli wolisz sposób topienia/przechylenia, możesz opublikować to, co wypróbowałeś i zobaczyć, czy ktoś może to naprawić lub poprawić. – JohnE

+0

Dzięki @JohnE. Powodem, dla którego go nie opublikowałem, jest to, że za każdym razem, gdy myślałem, że jestem blisko, zdaję sobie sprawę, jak daleko jestem w rzeczywistości. Myślę, że muszę zrobić jeszcze więcej badań i naprawdę kładę nacisk na to, jak działa wielopindeksowanie ramek danych w Pandach, zanim spróbuję bardziej usprawnionej wersji tego. Też myślę, że pomoc w innych obszarach, nad którymi pracuję. – nordicray

Powiązane problemy