想象一下,您有两个数据框。 两者都有一个“名称”列,其值完全相同(此处:A、B、C、D)。 现在,应在相应名称之间检查“值”。
import pandas as pd
import numpy as np
import datetime as dt
df_base = pd.DataFrame({
'name': ['A','B','C','D','E'],
'value': ['x', 'y',np.nan,'x',np.nan],
'date': ['01-01-1980','01-01-1980',np.nan,'01-01-1980',np.nan]})
df_upd = pd.DataFrame({
'name': ['A','B','C','D'],
'value': ['x', np.nan,'x','y']})
如果值不同,则应按表中所示更新 df_base['date']。 x = x 相同并且应保持旧值。 np.nan = np.nan 在日期中也有 np.nan,并且应保持不变。所有其他情况均应作为差异处理并以当前日期更新。
| name | value (df_base) | value (df_upd) |date (old)| date(new) |
|------|-----------------|----------------|----------|---------------|
| A | x | x |01-01-1980| 01-01-1980 |
| B | y | np.nan |01-01-1980|dt.date.today()|
| C | np.nan | x | np.nan |dt.date.today()|
| D | x | y |01-01-1980|dt.date.today()|
| E | np.nan | np.nan | np.nan | np.nan |
最后,我想要这个:
df_base = pd.DataFrame({
'name': ['A','B','C','D','E'],
'value': ['x', 'y',np.nan,'x',np.nan],
'date': ['01-01-1980','*today*','*today*','*today*',np.nan]})
merge
两个 dfs 然后用今天的值更新 date
如果值不同并且都不是 NaN
:
cmp = df_base.merge(df_upd, on="name", how="left", suffixes=(None, "_upd"))
# are both values NaN ?
m1 = cmp[["value", "value_upd"]].isna().all(axis=1)
# has the value been updated ?
m2 = cmp["value"].eq(cmp.pop("value_upd"))
cmp["date"] = cmp["date"].where(m1|m2, # or maybe you want %-d-%m-%Y ?
pd.Timestamp("today").strftime("%m-%d-%Y"))
输出:
print(cmp)
name value date
0 A x 01-01-1980
1 B y 10-28-2023
2 C NaN 10-28-2023
3 D x 10-28-2023
4 E NaN NaN