2013-02-15 12 views
7

我無法獲得「空」內部連接以使用MultiIndex。在0.10.1,我有:如果沒有重疊,MultiIndex的內部連接失敗

d1 = pd.DataFrame({ 
    'i1': [1, 2, 2], 
    'i2': [1, 1, 2], 
    'a': [10,20,30]}).set_index(['i1', 'i2']) 
d2 = pd.DataFrame({ 
    'i1': [3, 3], 
    'i2': [1, 2], 
    'b': [40, 50]}).set_index(['i1', 'i2']) 
d1.join(d2, how='inner') 

這給了我

Exception: Cannot infer number of levels from empty list 

有沒有解決這個什麼好辦法?我希望能夠預先知道路口是空的,所以我可以避免這種例外。

回答

5

這是easier to ask forgiveness than permission

import pandas as pd 
d1 = pd.DataFrame({'i1': [1, 2, 2], 'i2': [1, 1, 2], 'a': [10, 20, 30]} 
       ).set_index(['i1', 'i2']) 
d2 = pd.DataFrame(
    {'i1': [3, 3], 'i2': [1, 2], 'b': [40, 50]}).set_index(['i1', 'i2']) 
try: 
    d1.join(d2, how='inner') 
except Exception as err: 
    # Change this to however you wish to handle this case. 
    print(err) 
2

我不是這個100%,但在做外連接和刪除在NAS是一樣的內部連接。所以在沒有匹配的情況下,你只需要一個空的數據框。如果我們修改您的示例包括一個匹配的記錄,這似乎是這樣的:

import pandas as pd 
d1 = pd.DataFrame({ 
    'i1': [1, 2, 2], 
    'i2': [1, 1, 2], 
    'a': [10,20,30]}).set_index(['i1', 'i2']) 
d2 = pd.DataFrame({ 
    'i1': [1, 3], 
    'i2': [1, 2], 
    'b': [40, 50]}).set_index(['i1', 'i2']) 
d3 = d1.join(d2, how='outer').dropna() 
d4 = d1.join(d2, how='inner') 

其中給出:

In [9]: d3 
Out[9]: 
     a b 
i1 i2   
1 1 10 40 

In [10]: d4 
Out[10]: 
     a b 
i1 i2   
1 1 10 40 

和外後,所以加入+ dropna(),你可以看到有多少行d3並從那裏出發。使用你原來的例子:

import pandas as pd 
d1 = pd.DataFrame({ 
    'i1': [1, 2, 2], 
    'i2': [1, 1, 2], 
    'a': [10,20,30]}).set_index(['i1', 'i2']) 
d2 = pd.DataFrame({ 
    'i1': [3, 3], 
    'i2': [1, 2], 
    'b': [40, 50]}).set_index(['i1', 'i2']) 
d3 = d1.join(d2, how='outer').dropna() 
print(d3.shape) # no error, shows "(0, 2)" 
1

由塊合併來自HDFstore塊多索引節點得到了在for循環他的問題。像這樣解決了醜陋,稍後可能對其他人有所幫助。

import pandas as pd 
d1 = pd.DataFrame({ 
    'i1': [1, 2, 2], 
    'i2': [1, 1, 2], 
    'a': [10,20,30]}).set_index(['i1', 'i2']) 
d2 = pd.DataFrame({ 
    'i1': [3, 3], 
    'i2': [1, 2], 
    'b': [40, 50]}).set_index(['i1', 'i2']) 
for x in y: 
    try: 
     d3 = d1.join(d2, how='inner') 
    except Exception:    
     print "no merge possible between rows, but let's continue" 
     d3 = d1.join(d2, how='outer').dropna() 
    if len(d3) 
     print "there's a merge" 
     #action 
    print "fail, but still in the race"