2013-06-09 12 views
9

Niektóre z moich danych wygląda następująco:Python Pandy - łączące się głównie zduplikowane wiersze

date, name, value1, value2, value3, value4 
1/1/2001,ABC,1,1,, 
1/1/2001,ABC,,,2, 
1/1/2001,ABC,,,,35 

Próbuję dostać się do punktu, w którym mogę uruchomić

data.set_index(['date', 'name']) 

Ale, jak z danymi -jest oczywiście duplikatami (jak pokazano powyżej), więc nie mogę tego zrobić (i nie chcę indeksu z duplikatami, i nie mogę po prostu drop_duplicates(), ponieważ to by utraciło dane).

Chciałbym móc wymusić wiersze, które mają te same wartości [data, nazwa] w jednym wierszu, jeśli można je pomyślnie konwergować na podstawie pewnych wartości NaN (podobnie do zachowania combined_first()) . Na przykład, powyższa skończy się na

date, name, value1, value2, value3, value4 
1/1/2001,ABC,1,1,2,35 

Jeśli dwie wartości są różne i nie jest NaN, dwa wiersze nie powinny być konwergentnych (to będzie prawdopodobnie błąd, że muszę do kontynuacji).

(Aby przedłużyć powyższy przykład, w rzeczywistości może być dowolna liczba linii - ze względu na dowolną liczbę kolumn. - co powinno być możliwe zbiegały się jednym wierszu)

to czuje jak problem, który powinien być bardzo rozwiązalny przez pandy, ale mam problem ze znalezieniem eleganckiego rozwiązania.

Odpowiedz

11

Wyobraźmy sobie, że masz jakąś funkcję combine_it, która, biorąc pod uwagę zestaw wierszy, które miałyby powielone wartości, zwraca pojedynczy wiersz. Po pierwsze, grupa przez date i name:

grouped = data.groupby(['date', 'name']) 

Następnie wystarczy zastosować funkcję agregacji i wysięgnik skończysz:

result = grouped.agg(combine_it) 

Można również dostarczyć różne funkcje agregacji dla różnych kolumn przekazując agg dykt.

+0

Dzięki, że zdecydowanie ogranicza kluczowy krok. Czy jest to szczególnie skuteczny idiom? Z mojego doświadczenia (i wstępnego testowania za pomocą twojej sugestii), .agg() może spowodować bardzo powolne wykonywanie (prawdopodobnie nie dziwi). Może nieuniknione? – severian

+0

Może? Możesz spróbować użyć wbudowanych funkcji numpy ("sum", "max", itp.), Aby przyspieszyć (co wykorzystuje funkcje cytonizowane). Jest to prawdopodobnie poza zwykłym przypadkiem użycia dla groupby, ponieważ prawdopodobnie kończysz z wieloma grupami w stosunku do całkowitego rozmiaru DataFrame. –

+0

Cóż, z inną odpowiedzią, przynajmniej wiem, że nie przeoczyłem niczego zbyt oczywistego ... – severian

0

Jeśli nie masz wartości pola numerycznego, agregacja z licznikiem, min., Sumą itp. Nie będzie ani możliwa, ani sensowna. Mimo to nadal możesz chcieć zwinąć zduplikowane rekordy do poszczególnych rekordów (np.) W oparciu o jeden lub więcej kluczy podstawowych.

# Firstly, avoid Nan values in the columns you are grouping on! 
df[['col1', 'col2']] = df[['col1', 'col2']].fillna('null') 


    # Define your own customized operation in pandas agg() function 
df = df.groupby(['col1', 'col2']).agg({'SEARCH_TERM':lambda x: ', '.join(tuple(x.tolist())), 

            'HITS_CONTENT':lambda x: ', '.join(tuple(x.tolist()))} 
            ) 

Grupa przez jedną lub więcej kolumn i upadku wartości wartości poprzez przekształcenie ich w pierwszej kolejności, do listy, a następnie do krotki i wreszcie do łańcucha. Jeśli wolisz, możesz również zachować je jako listę lub krotkę zapisaną w każdym polu lub zastosować ag. funkcja i słownik bardzo różnych operacji do różnych kolumn.