根据索引和列将填充数据帧合并到掩码中

Merge a filling DataFrame into a mask, based on index and columns

使用以下 'mask' DataFrame:

>>> mask
               city      value_1      value_2
index
0            London           10          NaN
1             Paris          NaN           21
2             Paris           30          NaN
3             Paris          NaN          NaN
4            Berlin            3            5
5            Berlin          NaN           10
6          New York          NaN          NaN

和以下 'filling' 帧:

>>> filling
                value_1      value_2
London             1100         2100
Paris              1150         2200
Berlin              NaN         3000
New York           5000          NaN

如何根据 city AND 列将 filling 合并到 mask 中,以便生成的 DataFrame 变为:

>>> result
               city      value_1      value_2
index
0            London           10         2100
1             Paris         1150           21
2             Paris           30         2200
3             Paris         1150         2200
4            Berlin            3            5
5            Berlin          NaN           10
6          New York         5000          NaN

从概念上讲,mask 中的任何值 NaN 都可能被 filling 的值“填充”,该值同时匹配其 city 及其列(value_1value_2)。

我正在努力解决的部分是让 DataFrame.merge() 考虑索引(此处为 city)和所有列。两者都可以,但为了获得预期的结果,我似乎两者都需要。

编辑:

我试过以下方法:

>>> expanded = mask[[]].join(filling, on='city')
>>> mask.merge(expanded)

但这只会让我返回 mask,并且 expanded 中的所有值都将被忽略(即使目标单元格是 NaN)。

尝试 fillnareindexfilling:

mask.fillna(filling.reindex(mask.city).set_index(mask.index))

输出:

           city  value_1  value_2
index                            
0        London     10.0   2100.0
1         Paris   1150.0     21.0
2         Paris     30.0   2200.0
3         Paris   1150.0   2200.0
4        Berlin      3.0      5.0
5        Berlin      NaN     10.0
6      New York   5000.0      NaN

为此我们可以使用 DataFrame.updateoverwrite=False

注意:我们将方法分开放在不同的行中,因为更新是就地进行的。

mask = mask.set_index("city")
mask.update(filling, overwrite=False)
mask = mask.reset_index()

       city  value_1  value_2
0    London     10.0   2100.0
1     Paris   1150.0     21.0
2     Paris     30.0   2200.0
3     Paris   1150.0   2200.0
4    Berlin      3.0      5.0
5    Berlin      NaN     10.0
6  New York   5000.0      NaN

您也可以使用专为此目的设计的combine_first

print (mask.set_index("city").combine_first(filling))

          value_1  value_2
Berlin        3.0      5.0
Berlin        NaN     10.0
London       10.0   2100.0
New York   5000.0      NaN
Paris      1150.0     21.0
Paris        30.0   2200.0
Paris      1150.0   2200.0

如果您需要保留原来的顺序,请先reset_index然后再排序。