根据索引和列将填充数据帧合并到掩码中
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_1
或 value_2
)。
我正在努力解决的部分是让 DataFrame.merge()
考虑索引(此处为 city
)和所有列。两者都可以,但为了获得预期的结果,我似乎两者都需要。
编辑:
我试过以下方法:
>>> expanded = mask[[]].join(filling, on='city')
>>> mask.merge(expanded)
但这只会让我返回 mask
,并且 expanded
中的所有值都将被忽略(即使目标单元格是 NaN
)。
尝试 fillna
与 reindex
共 filling
:
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.update
和 overwrite=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
然后再排序。
使用以下 '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_1
或 value_2
)。
我正在努力解决的部分是让 DataFrame.merge()
考虑索引(此处为 city
)和所有列。两者都可以,但为了获得预期的结果,我似乎两者都需要。
编辑:
我试过以下方法:
>>> expanded = mask[[]].join(filling, on='city')
>>> mask.merge(expanded)
但这只会让我返回 mask
,并且 expanded
中的所有值都将被忽略(即使目标单元格是 NaN
)。
尝试 fillna
与 reindex
共 filling
:
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.update
和 overwrite=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
然后再排序。