python - 仅当列没有值时,Pandas DataFrame 才从另一个数据帧更新

标签 python pandas dataframe

我正在尝试使用另一个数据帧中的值来更新数据帧,但我希望仅当特定列没有值时才会进行更新。

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](当前日期)的值,我想使用 df2 中的值更新 df1

因此,在上面的示例中,只应更新 df1 中的第二行。

我尝试如下更新,但不确定如何根据列是否有值进行过滤

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

最佳答案

更新:这似乎是 filter_func 参数的明显用途。仅更新 df1 所有列均为 null 的行:

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)

关于python - 仅当列没有值时,Pandas DataFrame 才从另一个数据帧更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58884570/

相关文章:

python - 测试文档字符串是否存在

Python pandas - 提取和替换

python - 如何获取 Pandas DataFrame 中 2 个列表的差异?

python - 如何获取pandas数据框中前一列的值?

python - 如何在 Mac 上构建和安装 libvirt?

python - 如何在 python 字典上使用 $push/$addToSet mongodb 更新修饰符

python - 将 UTC 时间字符串的 pandas 数据帧列转换为 float

pandas:按二级索引范围将值分配给多索引切片

python - 如何在 Pandas 中按降序对两列进行排序?

python - Pandas :超链接到数据框中的一列