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

Python Pandas外部合并返回不合适的值和额外的NaN,python,pandas,merge,Python,Pandas,Merge,我有两个数据帧:fpm和real。见以下示例: 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 530

我有两个数据帧:
fpm
real
。见以下示例:

          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
我想按
地区id
月份
合并它们

为此,我使用了以下命令:

j = pd.merge(real, fpm, how='outer', on=['region_id', 'month'], left_index='off', right_index='off')
发生的情况是,
fpm
列中的一些外来值加入了
地区id 5300108
的同一行,而实际的
gdp地区
实际上没有在正确的
地区id
月份
加入

我已经检查过,两列的类型相同:
int

这是错误的结果。请注意,索引是不同的。我明确地设置了
index='off'

   region_id  month    gdp_region           fpm
72397    5300108     35  5.390220e+10  1.649367e+07
72398    5300108     47  5.845612e+10  1.968157e+07
72399    5300108     59  6.707650e+10  2.088269e+07
72400    5300108     71  7.573268e+10  4.027545e+06
72401    5300108     83  8.466141e+10  1.197713e+06
72402    5300108     95  9.340400e+10  1.383501e+06
72403    5300108    107  1.102996e+11  1.718117e+06
72404    5300108    119  1.243238e+11  1.827867e+06
72405    5300108    131  1.441741e+11  2.053814e+06
72406    5300108    143  1.545690e+11  2.597804e+06
72407    5300108    155  1.641013e+11  2.908494e+06
72408    5300108    167  1.759067e+11  3.394452e+06
72409    5300108    179  1.974321e+11  4.022392e+06
94934    5300108     11           NaN  3.106522e+07
94935    5300108     23           NaN  3.476453e+07
94936    5300108     35           NaN  4.480962e+07
94937    5300108     47           NaN  4.148533e+07
94938    5300108     59           NaN  4.324909e+07
94939    5300108     71           NaN  5.908792e+07
94940    5300108     83           NaN  6.218772e+07
94941    5300108     95           NaN  6.881312e+07
感谢您的建议。
谢谢

试试这样简单的方法

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

如前所述,“如果在列上连接列,则数据帧索引将被忽略。否则,如果在索引上连接索引或在一列或多列上连接索引,则索引将被传递。”

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

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\u index='off'
等不是pandas支持的方式。它使用布尔值,默认值设置为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
如果这不是您的结果,那么可能在名为“real”的数据帧中有一个名为“fpm”的额外列。但是,我可以通过设置
left\u index=True,right\u 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

一个可重复输入的代码片段会很有帮助。您所需的输出也是如此。您可以先使用
left_index=False
而不是“Off”来尝试此操作:

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)
这是否代表您期望的输出


pd.merge(real,fpm,how='left',on=['region\u id','month'])
如果我使用how='left',我丢失了11个月的'fpm'信息。然后使用
how='right'
正如我所说(上面的评论),生成的框架没有我没有gdp\u地区的fpm信息(例如,第11个月)。因此,我丢失了信息。我想要一个尽可能完整的表格,尽管带有
Nan
,其中我的信息实际上从原始表格中丢失了database@BFurtado尝试
how='outer'
,您将获得
NaN
值,这是您的预期输出。这正是我在示例中所做的。但是请注意结果不正确。NAN是好的。但是同一个月和地区的id的值不同fpm@BFurtado我这样做是出于我的记忆,如果是这样的话,你必须添加
left\u index=True,right\u index=True
,正如pandas文档中引用的那样。我将更新答案。请重新更新答案,因为使用
left_index=True
right\u index=True
两者都会产生OP的问题。我只使用其中的一个不会遇到麻烦,但仍然会产生无意义的索引。:)有趣的是,您的实现代表了所需的输出。但是,我的实际数据并非如此。我猜这意味着问题不在merge命令中,而是在DataFrames的数据中的某个地方?哇。想想看。现在我做了
d=real
e=fpm
f=pd。合并(d,e,how='outer',on=['region\u id','month'])
,结果成功了!谢谢虽然我仍然不明白为什么没有一个好的答案。这一定是数据帧生成的问题。也许吧。实际上,上的变量类型必须匹配!这就是关键。很酷,你找到了答案。是的,@vestland,但是,第一次Python让我失望。在我进行连续的合并时,pandas不断地将我的
int
放入
float
。无论如何,如果您测试
int(1)==float(1)
Python会返回它应该返回的
True
。要吸取的教训:在熊猫中始终使用字符串作为键!