如果没有重叠,则使用MultiIndex的内部联接会失败

时间:2013-02-15 18:10:48

标签: python pandas

我不能使用“空”内连接来使用MultiIndex。在0.10.1之下,我有:

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

这有什么好办法吗?我希望能够预先判断交叉点是否为空,所以我可以避免异常。

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:2)

我不是百分之百,但是做外连接并删除NA与内连接相同。因此,在没有匹配的指标的情况下,您只需获得一个空的数据帧。如果我们修改您的示例以包含一个匹配记录,则情况似乎如此:

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)"

答案 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"