Multiindex Merge返回空df,但join应该有效

时间:2018-02-21 23:08:30

标签: python pandas dataframe merge

我试图加入两个数据框,其中包括按国家/地区代码分列的总奥运奖牌数,以及按国家/地区代码和年份分列的年度和国家/地区总数。每个都是一列的数据框,具有相同的多索引(国家,人口)。

数据框架可能不一定包括相同的国家和年份,例如奥林匹克年份不像一般年份那么多,并且人口估算数据集中缺少一些国家/地区代码。一些摘录来说明数据结构,ITA以及部分重叠的一堆年份:

配有:

          Medals
Cty Year        
ITA 1960      88
    1964      50
    1968      32
    1972      25
    1976      31

流行:

          Population
Cty Year            
ITA 1960  50199700.0
    1961  50536350.0
    1962  50879450.0
    1963  51252000.0
    1964  51675350.0

当我使用此命令时,我得到一个空数据帧。

[In] df = pd.merge(med, pop, left_index=True, right_index=True)
[In] df
[Out] Empty DataFrame
Columns: [Medals, Population]
Index: []

我还试过在每个数据帧上使用reset_index然后传递:

[In] df = pd.merge(med, pop, on=['Cty','Year'])
[In] df
[Out] Empty DataFrame
Columns: [Cty, Year, Population, Medals]
Index: []

似乎已经创建了具有预期列名的数据框,但由于某种原因,它甚至无法合并两者中存在的Cty和Year索引的组合(这将是我对此内部联接的目标)。

根据我之前发布的两个数据子集,预期输出应如下所示:

          Medals  Population
Cty Year        
ITA 1960      88  50199700.0
    1964      50  51675350.0

我已经彻底搜索了这个网站和其他人,我无法绕过它!任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:1)

事实证明,问题不在于我的merge或concat语法,而是在Multiindex中,一个数据帧将Year存储为str,另一个存储为int64。

我使用以下代码将str进入int64,然后合并运算符按预期工作:

pop.index = pop.index.set_levels([pop.index.levels[0], pop.index.levels[1].astype(int)])

我之所以发布这个作为我自己帖子的答案,只是为了证明评论我感谢root的提示,以防其他人有类似的问题。

答案 1 :(得分:0)

看起来你需要内部合并:

import pandas as pd

med = pd.DataFrame([['ITA', 1960, 88],    
                    ['ITA', 1964, 50],
                    ['ITA', 1968, 32],
                    ['ITA', 1972, 25],
                    ['ITA', 1976, 31]],
                   columns=['Cty', 'Year', 'Medals'])

pop = pd.DataFrame([['ITA', 1960, 50199700],    
                    ['ITA', 1961, 50536350],
                    ['ITA', 1962, 50879450],
                    ['ITA', 1963, 51252000],
                    ['ITA', 1964, 51675350]],
                   columns=['Cty', 'Year', 'Population'])

med = med.set_index(['Cty', 'Year'])
pop = pop.set_index(['Cty', 'Year'])

pd.merge(med, pop, how='inner', left_index=True, right_index=True)

#           Medals  Population
# Cty Year                    
# ITA 1960      88    50199700
#     1964      50    51675350

答案 2 :(得分:0)

来自jpp的数据

pd.concat([pop,med],1).dropna()
Out[1496]: 
          Population  Medals
Cty Year                    
ITA 1960  50199700.0    88.0
    1964  51675350.0    50.0

或者只在inner

中设置concat
pd.concat([pop,med],axis=1, join='inner')
Out[1497]: 
          Population  Medals
Cty Year                    
ITA 1960    50199700      88
    1964    51675350      50