2013-06-07 25 views
9

Tôi có một khung dữ liệu Pandas có hai cột khóa và tôi muốn đảm bảo rằng sản phẩm Descartes của các khóa đó tồn tại trong bảng (vì tôi sẽ phải thực hiện Ô 2D chứa tất cả các kết hợp). Tôi đang gặp khó khăn trong việc đưa ra một cách hợp lý và ngắn gọn để làm điều này.đảm bảo các sản phẩm Descartes của các khóa xuất hiện trong một bảng Pandas

Ví dụ, tôi bắt đầu với bảng này đưa ra sự kết hợp của các loại trái cây và rau quả, và làm thế nào họ nếm với nhau:

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

Tôi muốn kết thúc với bảng này trong đó tất cả các kết hợp có thể xảy ra:

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 

đây là cách tốt nhất mà tôi đã tìm thấy để làm điều đó:

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' 

tôi hãy tưởng tượng rằng có một cách đơn giản hơn và ít bị lỗi hơn để làm điều này ... bất kỳ lời khuyên nào?

Tôi muốn đặc biệt đánh giá cao nếu ai đó có thể chỉ cho tôi cách để làm điều này cả hai có và không có một chỉ số đa chứa các cột fruitveg, bởi vì tôi thực sự bối rối về cách để làm điều này với chỉ số. Dựa trên kinh nghiệm SQL của tôi, tôi nghĩ rằng đây là chính xác các tình huống mà các chỉ mục được dự định.

Trả lời

10

Thỉnh thoảng sau câu trả lời này, tôi đã thêm cartesian_product vào gấu trúc và ngay sau khi MultiIndex.from_product được thêm vào (theo đề xuất của nó trong another question). Điều này cho phép đơn giản hóa sau đó là hiệu quả hơn:

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 

Câu trả lời cũ sau:


Nếu bạn sử dụng trái cây và rau như chỉ số, sau đó bạn có thể sử dụng itertools.product * để tạo ra các MultiIndex đến reindex bởi:

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 

Phần khó khăn là lấy đúng MultiIn dex của tất cả các hoa quả càng tốt/rau:

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']) 

Sau đó, bạn chỉ có thể reindex bởi những:

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 

* Nếu itertools.product là không đủ nhanh xem xét sử dụng this numpy implemention

Lưu ý: thực hiện này đã được mở rộng trong pandas.tools.util.cartesian_product, hiện hỗ trợ nhiều loại dtypes hơn (và được sử dụng dưới mui xe trong MultiIndex.from_product).

+0

Cảm ơn Andy, điều này rất phù hợp với tôi. Có vẻ như cũng có một đối số tùy chọn 'fill_value' cho reindex có thể lưu một bước (ví dụ:' df1.reindex (fruit_x_veg, fill_value = 'UNKNOWN') '. –

+0

@Dan Tuyệt vời! Oooh, gọn gàng :) –

+1

@Dan FYI có một [vấn đề github] gần đây (https://github.com/pydata/pandas/issues/3835) về việc thêm chức năng này một cách tự nhiên. –

Các vấn đề liên quan