2013-06-07 14 views
9

Mam pandową ramkę danych, która ma dwie kluczowe kolumny i chcę zapewnić, że kartezjański produkt tych kluczy istnieje w tabeli (ponieważ będę musiał wykonać Wykres 2D zawierający wszystkie kombinacje). Mam problem z wymyśleniem dość krótkiego i idiomatycznego sposobu na zrobienie tego.upewniając się, że kartezjański produkt kluczy pojawia się w tabeli Pandy

Na przykład, zacznę ten stół dając kombinacje owoców i warzyw, i jak smakują razem:

combo fruit  veg 
0 tasty apple carrot 
1 yucky banana carrot 
2 tasty banana lettuce 
3 yucky lemon lettuce 

Chcę skończyć z tej tabeli, w której występują wszystkie możliwe kombinacje:

fruit  veg combo 
0 apple carrot tasty 
1 apple lettuce UNKNOWN 
2 banana carrot yucky 
3 banana lettuce tasty 
4 lemon carrot UNKNOWN 
5 lemon lettuce yucky 

Oto najlepszy sposób znalazłem to zrobić:

import pandas as pd 

# Initial data 
df=pd.DataFrame(dict(fruit=['apple','banana','banana','lemon'], 
        veg=['carrot','carrot','lettuce','lettuce'], 
        combo=['tasty','yucky','tasty','yucky'])) 

# Solution starts here 
veg=df.groupby('veg').size().reset_index() 
fruit=df.groupby('fruit').size().reset_index() 
fruit[0] = veg[0] = 0 #use this dummy column for the join to work! 
cartesian = pd.merge(fruit, veg, how='outer', on=0) 
del cartesian[0] 
all_combos = pd.merge(cartesian, df, how='left') 
all_combos[ pd.isnull(all_combos.combo) ] = 'UNKNOWN' 

I wyobraź sobie, że musi być prostszy i mniej podatny na błędy sposób, aby to zrobić ... jakąkolwiek radę?

bym szczególnie wdzięczny, jeśli ktoś może mi pokazać jak to zrobić zarówno z jak i bez multi-indeks zawierający fruit i veg kolumn, bo jestem naprawdę zastanawiał się, jak to zrobić z indeksami. Bazując na moim doświadczeniu SQL, wydaje mi się, że są to dokładnie sytuacje, dla których przeznaczone są indeksy.

Odpowiedz

10

Jakiś czas po tej odpowiedzi dodałem cartesian_product do pand i wkrótce po dodaniu MultiIndex.from_product (zgodnie z sugestią w another question). Umożliwia to następujące uproszczenie, które jest bardziej efektywne:

In [21]: p = pd.MultiIndex.from_product(df1.index.levels, names=df1.index.names) 

In [22]: df1.reindex(p, fill_value='UNKNOWN') 
Out[22]: 
        combo 
fruit veg 
apple carrot  tasty 
     lettuce UNKNOWN 
banana carrot  yucky 
     lettuce tasty 
lemon carrot UNKNOWN 
     lettuce yucky 

Starsze odpowiedź następująco:


Jeśli używasz owoce i warzywa jako indeks, następnie można użyć itertools.product *, aby utworzyć MultiIndex do reindex przez:

In [10]: from itertools import product 

In [11]: df 
Out[11]: 
    combo fruit  veg 
0 tasty apple carrot 
1 yucky banana carrot 
2 tasty banana lettuce 
3 yucky lemon lettuce 

Najtrudniejsze jest chwycić prawą MultiIn dek wszystkich możliwych owoców/warzyw:

In [12]: fruit_x_veg = list(product(np.unique(df['fruit']), np.unique(df['veg']))) 

In [13]: fruit_x_veg = pd.MultiIndex.from_tuples(fruit_x_veg, 
               names=['fruit', 'veg']) 

Następnie można po prostu reindex przez nich: nie

In [14]: df1 = df.set_index(['fruit', 'veg']) 

In [15]: df1 
Out[15]: 
       combo 
fruit veg 
apple carrot tasty 
banana carrot yucky 
     lettuce tasty 
lemon lettuce yucky 

In [16]: df1.reindex(fruit_x_veg, fill_value='UNKNOWN') 
Out[16]: 
        combo 
fruit veg 
apple carrot  tasty 
     lettuce UNKNOWN 
banana carrot  yucky 
     lettuce tasty 
lemon carrot UNKNOWN 
     lettuce yucky 

* Jeśli itertools.product jest wystarczająco szybki, należy rozważyć użycie this numpy implemention

Uwaga: Ta realizację został rozszerzony w pandas.tools.util.cartesian_product, który obsługuje teraz więcej dtypów (i jest używany pod maską w MultiIndex.from_product).

+0

Dzięki, Andy, to działa dobrze dla mnie. Wygląda na to, że istnieje również opcjonalny argument "fill_value" do reindeksu, który może zapisać krok (np. 'Df1.reindex (fruit_x_veg, fill_value = 'UNKNOWN')'. –

+0

@Dan Excellent! Oooh, jak schludnie :) –

+1

@Dan FYI istnieje niedawny [problem github] (https://github.com/pydata/pandas/issues/3835) o dodawaniu tej funkcji natywnie. –

Powiązane problemy