Pandas外部合并返回不合适的值和额外的Nans

时间:2017-08-09 14:29:09

标签: python pandas merge

我有两个数据框:fpmreal。请参阅以下示例:

          month   fpm          region_id
94934     11  3.106522e+07    5300108
94935     23  3.476453e+07    5300108
94936     35  4.480962e+07    5300108
94937     47  4.148533e+07    5300108
94938     59  4.324909e+07    5300108
94939     71  5.908792e+07    5300108
94940     83  6.218772e+07    5300108
94941     95  6.881312e+07    5300108

        region_id  month    gdp_region
72397    5300108     35  5.390220e+10
72398    5300108     47  5.845612e+10
72399    5300108     59  6.707650e+10
72400    5300108     71  7.573268e+10
72401    5300108     83  8.466141e+10
72402    5300108     95  9.340400e+10

我想通过region_idmonth合并它们。

为了做到这一点,我使用了命令:

j = pd.merge(real, fpm, how='outer', on=['region_id', 'month'], left_index='off', right_index='off')

fpm列的某些外来值加入region_id 5300108的同一行时,实际的gdp_region实际上并未在正确的region_id和{{ 1}}。

我已检查并且两列的类型相同:month

这是错误的结果。请注意,INDEXES是不同的。我明确地设置了int

index='off'

感谢任何建议。 谢谢。

3 个答案:

答案 0 :(得分:2)

尝试这样简单的事情,

j = real.merge(fpm, how = 'right', on = ['region_id', 'month'])

正如pandas document所提到的,“如果在列上连接列,则会忽略DataFrame索引。否则,如果在列或列上的索引或索引上连接索引,则将传递索引”。

答案 1 :(得分:2)

对于几乎对称的解决方案,无论您执行哪种合并,月份都处于相同的顺序,您可以使用(几乎)等效的表达式:

j = fpm.merge(real, how = 'outer', on = ['region_id', 'month']).sort_values('month')

j2 = real.merge(fpm, how = 'outer', on = ['region_id', 'month']).sort_values('month')

j3 = pd.merge(real, fpm, how = 'outer', on = ['region_id', 'month']).sort_values('month')

请注意,left_index='off'等不是熊猫支持的方式。它使用布尔值,其默认值设置为False,这正是您想要的行为。

它为我回报:

   month         fpm  region_id    gdp_region
0     11  31065220.0    5300108           NaN
1     23  34764530.0    5300108           NaN
2     35  44809620.0    5300108  5.390220e+10
3     47  41485330.0    5300108  5.845612e+10
4     59  43249090.0    5300108  6.707650e+10
5     71  59087920.0    5300108  7.573268e+10
6     83  62187720.0    5300108  8.466141e+10
7     95  68813120.0    5300108  9.340400e+10

如果这不是您的结果,那么可能在您的数据框中有一个名为“fpm”的额外列,名为“real”。但是,我可以通过设置left_index=True, right_index=True重新创建原始问题,因此我认为使用“off”的关键字定义使python解释为布尔True而不是所需的行为。

现在,使用left_index=True将填充缺失的索引,因为数据长度与上一个已知索引值不同:

j4 = pd.merge(fpm, real, how = 'outer', on = ['region_id', 'month'], left_index=True, right_index=False).sort_values('month')
           month         fpm  region_id    gdp_region
72402     11  31065220.0    5300108           NaN
72402     23  34764530.0    5300108           NaN
72397     35  44809620.0    5300108  5.390220e+10
72398     47  41485330.0    5300108  5.845612e+10
72399     59  43249090.0    5300108  6.707650e+10
72400     71  59087920.0    5300108  7.573268e+10
72401     83  62187720.0    5300108  8.466141e+10
72402     95  68813120.0    5300108  9.340400e+10

反过来说,索引保留:

j5 = pd.merge(fpm, real, how = 'outer', on = ['region_id', 'month'], left_index=False, right_index=True).sort_values('month')
       month         fpm  region_id    gdp_region
94934     11  31065220.0    5300108           NaN
94935     23  34764530.0    5300108           NaN
94936     35  44809620.0    5300108  5.390220e+10
94937     47  41485330.0    5300108  5.845612e+10
94938     59  43249090.0    5300108  6.707650e+10
94939     71  59087920.0    5300108  7.573268e+10
94940     83  62187720.0    5300108  8.466141e+10
94941     95  68813120.0    5300108  9.340400e+10

同时使用True只会使用所有索引值组合,最终会得到很多NaN,或者如果你有实际数据,可能会填充特定索引的值价值组合:

j6 = pd.merge(fpm, real, how = 'outer', on = ['region_id', 'month'], left_index=True, right_index=True).sort_values('month')
       month         fpm  region_id    gdp_region
94934     11  31065220.0    5300108           NaN
94935     23  34764530.0    5300108           NaN
72397     35         NaN    5300108  5.390220e+10
94936     35  44809620.0    5300108           NaN
72398     47         NaN    5300108  5.845612e+10
94937     47  41485330.0    5300108           NaN
72399     59         NaN    5300108  6.707650e+10
94938     59  43249090.0    5300108           NaN
72400     71         NaN    5300108  7.573268e+10
94939     71  59087920.0    5300108           NaN
72401     83         NaN    5300108  8.466141e+10
94940     83  62187720.0    5300108           NaN
72402     95         NaN    5300108  9.340400e+10
94941     95  68813120.0    5300108           NaN

答案 2 :(得分:1)

可重复输入的代码段会很有帮助。您想要的输出也是如此。您可以先使用left_index = False而不是'关闭'

尝试此操作
import pandas as pd

fpm = pd.DataFrame({'idx':[94934,94935,94936,94937,94938,94939,94940,   94941],
                   'month': [11,23,35,47,59,71,83,95],
                   'fpm':   [3.106522e+07,3.476453e+07,4.480962e+07,    4.148533e+07,   4.324909e+07,   5.908792e+07,6.218772e+07,6.881312e+07],
                   'region_id':[5300108,5300108,5300108,5300108,5300108,5300108,5300108,5300108]})
fpm = fpm.set_index(['idx'])

real = pd.DataFrame({'idx':[72397,72398,72399,72400,72401,72402],
                   'region_id':[5300108,5300108,5300108,5300108,5300108,5300108],
                   'month':[35,47,59,71,83,95],
                    'gdp_region':[5.390220e+10,5.845612e+10,6.707650e+10,7.573268e+10,8.466141e+10,9.340400e+10]})

real = real.set_index(['idx'])

j = pd.merge(real, fpm, how='outer', on=['region_id', 'month'], left_index=False, right_index=False).sort_values(['region_id', 'month'])
print(j)

这是否代表您想要的输出?

enter image description here