Python 基于索引组合两个数据帧,替换其他列中的匹配值

Python 基于索引组合两个数据帧,替换其他列中的匹配值,python,pandas,replace,Python,Pandas,Replace,我有以下宽df1: Area geotype type ... 1 a 2 ... 1 a 1 ... 2 b 4 ... 4 b 8 ... 以及以下两列df2: Area geotype 1 London 4 Cambridge 我想要的是: Area geotype type ... 1 London

我有以下宽df1:

Area geotype  type    ...
1      a        2      ...
1      a        1      ... 
2      b        4      ...
4      b        8      ...
以及以下两列df2:

Area   geotype
1      London
4      Cambridge
我想要的是:

Area  geotype  type    ...
1     London     2      ...
1     London     1      ... 
2       b        4      ...
4     Cambridge  8      ...
因此,我需要基于非唯一区域列进行匹配,然后仅当存在匹配时,才替换geotype列中的设置值

抱歉,如果这是重复的,我确实在努力寻找解决方案。

我认为您可以使用创建的
系列
,然后通过或填充
NaN
值:

另一个解决方案包括和:

按注释编辑:

问题不是唯一的
ID
值,如
df2
中的值:

df2 = pd.DataFrame({'ID': [1, 1, 4], 'geotype': ['London', 'Paris', 'Cambridge']})
print (df2)
   ID    geotype
0   1     London
1   1      Paris
2   4  Cambridge
因此函数
map
无法选择正确的值并引发错误

解决方案是删除重复项,默认情况下保留第一个值:

df2 = df2.drop_duplicates('ID')
print (df2)
   ID    geotype
0   1     London
2   4  Cambridge
或者,如果需要保留最后一个值:

df2 = df2.drop_duplicates('ID', keep='last')
print (df2)
   ID    geotype
1   1      Paris
2   4  Cambridge

如果无法删除重复项,则有另一种解决方案使用outer,但在
df2
中有重复的
ID
行:

df1 = pd.merge(df1, df2, on='ID', how='outer', suffixes=('_',''))
df1.geotype = df1.geotype.combine_first(df1.geotype_)
df1 = df1.drop('geotype_', axis=1)
print (df1)
   ID type    geotype
0   1    2     London
1   1    2      Paris
2   2    1          a
3   3    4          b
4   4   8e  Cambridge
替代解决方案:

In [78]: df1.loc[df1.ID.isin(df2.ID), 'geotype'] = df1.ID.map(df2.set_index('ID').geotype)

In [79]: df1
Out[79]:
   ID    geotype  type
0   1     London     2
1   2          a     1
2   3          b     4
3   4  Cambridge     8
更新:回答更新的问题-如果您在
df2
DF的
区域
列中有重复项:

In [152]: df1.loc[df1.Area.isin(df2.Area), 'geotype'] = df1.Area.map(df2.set_index('Area').geotype)
...
skipped
...
InvalidIndexError: Reindexing only valid with uniquely valued Index objects

get rid of duplicates:

In [153]: df1.loc[df1.Area.isin(df2.Area), 'geotype'] = df1.Area.map(df2.drop_duplicates(subset='Area').set_index('Area').geotype)

In [154]: df1
Out[154]:
   Area    geotype  type
0     1     London     2
1     1     London     1
2     2          b     4
3     4  Cambridge     8

使用
update
+
map

df1.geotype.update(df1.Area.map(df2.set_index('Area').geotype))

   Area    geotype  type
0     1     London     2
1     1     London     1
2     2          b     4
3     4  Cambridge     8

很抱歉,我得到了“仅对唯一值索引对象重新索引有效”,因为ID列实际上是一个区域列,所以有多个条目。我发现了问题-您在
df2
中有一个
ID
多个值,所以
map
是不可能的-熊猫不知道是需要第一个值还是第一个
ID
。您需要在
df2
中使用唯一的
ID
值抱歉,我得到了“仅对唯一值索引对象重新索引有效”,因为ID列实际上是一个区域列,因此有多个条目。@请确认,
df2
DF中是否也有重复项?在df1中没有重复项@MaxU@jezrael固定的。
In [152]: df1.loc[df1.Area.isin(df2.Area), 'geotype'] = df1.Area.map(df2.set_index('Area').geotype)
...
skipped
...
InvalidIndexError: Reindexing only valid with uniquely valued Index objects

get rid of duplicates:

In [153]: df1.loc[df1.Area.isin(df2.Area), 'geotype'] = df1.Area.map(df2.drop_duplicates(subset='Area').set_index('Area').geotype)

In [154]: df1
Out[154]:
   Area    geotype  type
0     1     London     2
1     1     London     1
2     2          b     4
3     4  Cambridge     8
df1.geotype.update(df1.Area.map(df2.set_index('Area').geotype))

   Area    geotype  type
0     1     London     2
1     1     London     1
2     2          b     4
3     4  Cambridge     8