我正在尝试使用另一个数据框中的值来更新数据框,但是我希望仅在特定列没有值的情况下进行更新。
from datetime import datetime
import pandas as pd
dr = pd.bdate_range(periods=3, end=datetime.now().date())
df1 = pd.DataFrame([1, 2], columns=['myid'])
for d in dr:
df1[d.to_pydatetime()] = pd.np.nan
df1.loc[df1['myid'] == 1, dr[2]] = 4.0
df1 = df1.set_index('myid')
df1
2019-11-13 00:00:00 2019-11-14 00:00:00 2019-11-15 00:00:00
myid
1 NaN NaN 4.0
2 NaN NaN NaN
df2 = pd.DataFrame([1, 2], columns=['myid'])
for d in dr:
df2[d.to_pydatetime()] = pd.np.nan
df2.loc[df2['myid'] == 2, dr[2]] = 4.0
df2.loc[df2['myid'] == 1, dr[0]] = 6.0
df2 = df2.set_index('myid')
df2
2019-11-13 00:00:00 2019-11-14 00:00:00 2019-11-15 00:00:00
myid
1 6.0 NaN NaN
2 NaN NaN 4.0
如果df1没有dr[2] (current date)
的值,我想用df2中的值更新df1。
因此,在上面的示例中,仅df1中的第二行应被更新。
我尝试了update
,但不确定如何根据列是否有值进行过滤
df1.update(df2, overwrite=False)
我确实查看了更新所需的filter_func
,但再次无法使用它。任何帮助深表感谢。谢谢
编辑:
预期输出:
不应触摸行1,因为它在列2019-11-15 00:00:00
中已经有一个值
df1
2019-11-13 00:00:00 2019-11-14 00:00:00 2019-11-15 00:00:00
myid
1 NaN NaN 4.0
2 NaN NaN 4.0
答案 0 :(得分:0)
更新:这似乎是filter_func
参数的明显用法。仅更新df1
的所有列均为空的行:
df1.update(df2, filter_func=lambda df: df1.isnull().all(1))
# 2019-11-13 00:00:00 2019-11-14 00:00:00 2019-11-15 00:00:00
#myid
#1 NaN NaN 4.0
#2 NaN NaN 4.0
旧答案,更多实际操作:
您可以分隔要更新的行,仅更新那些行,然后合并。 update
在原地运行,因此我们需要将其分解。
m = df1.notnull().any(1)
# These get updated
u = df1[~m].copy()
u.update(df2)
df1 = pd.concat([df1[m], u])
# 2019-11-13 00:00:00 2019-11-14 00:00:00 2019-11-15 00:00:00
#myid
#1 NaN NaN 4.0
#2 NaN NaN 4.0
或者,您可以使用combine_first
,然后屏蔽不应该更新的行并将其重置为df1
中的原始值
df1.combine_first(df2).mask(df1.notnull().any(1)).fillna(df1)