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

时间:2017-01-19 20:17:03

标签: python pandas replace

我有以下广泛的df1:

Integer a = new Integer(1);     // a is 1
Integer b = new Integer(2);     // b is 2
a = b;                          // a now is 2
a++;                            // a now is 3
System.out.print(a + " " + b);

以下两栏df2:

Area geotype  type    ...
1      a        2      ...
1      a        1      ... 
2      b        4      ...
4      b        8      ...

我想要以下内容:

Area   geotype
1      London
4      Cambridge

所以我需要根据非唯一的Area列进行匹配,然后只有匹配时才替换地理列中的设置值。

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

3 个答案:

答案 0 :(得分:3)

使用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

答案 1 :(得分:2)

我认为您可以使用Series创建的NaN使用map,然后按set_indexcombine_first填充df1.geotype = df1.ID.map(df2.set_index('ID')['geotype']).combine_first(df1.geotype) #df1.geotype = df1.ID.map(df2.set_index('ID')['geotype']).fillna(df1.geotype) print (df1) ID geotype type 0 1 London 2 1 2 a 1 2 3 b 4 3 4 Cambridge 8e 值:

df1.geotype = df1.geotype.mask(np.in1d(df1.ID, df2.ID),
                               df1.ID.map(df2.set_index('ID')['geotype']))
print (df1)
   ID    geotype type
0   1     London    2
1   2          a    1
2   3          b    4
3   4  Cambridge   8e

fillnamask的另一种解决方案:

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 无法选择正确的值并引发错误。

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

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

或者如果需要保留最后一个值:

ID

如果无法删除重复项,则会有另一个外部drop_duplicates的解决方案,但df2中存在重复的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 重复行:

a++

答案 2 :(得分:2)

替代解决方案:

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

更新回答已更新问题 - 如果您在Area DF的df2列中有重复项:

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