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
。要吸取的教训:在熊猫中始终使用字符串作为键!