【问题标题】:Check if NaT changes to datetime and update value检查 NaT 是否更改为日期时间并更新值
【发布时间】:2021-04-17 21:18:11
【问题描述】:

我有以下数据框。

df_1:

order_id   date
123        2020-01-01
456        NaT
789        2020-10-10
135        2020-05-31
234        NaT
111        NaT

df_2:

order_id   date
123        2020-01-02
456        2021-01-01
789        2020-10-11
135        2020-6-01

输出应捕获日期从上一个条目更改为未来日期和/或 NaT 更改为新日期的任何时间。

new_df 应该等于:

order_id   date
123        2020-01-02
456        2021-01-01
789        2020-10-11
135        2020-6-01

我尝试过的:

df_1['date'] = pd.to_datetime(
    df_1['date'])
df_2['date'] = pd.to_datetime(
    df_2['date'])
s = df_2.set_index('order_id')['date']

mapped = df_1['order_id'].map(s)
mask = mapped > df_1['date']
df_1.loc[mask, 'date'] = mapped

这仅在日期更改为未来日期时进行更改,但在 NaT 变为新日期时不会捕获。

【问题讨论】:

  • 生成的数据框是 df_2 的精确副本。

标签: python-3.x pandas dataframe series


【解决方案1】:

在将日期强制为 datetime 后使用 np.where。

import numpy as np
df_1['date']=pd.to_datetime(df_1['date'])
df_2['date']=pd.to_datetime(df_2['date'])
df=pd.merge(df_2,df_1, how='left', on='order_id',suffixes=('_left', ''))
df=df.assign(date=np.where(df['date'].isna()|df['date_left'].sub(df['date']).dt.days.gt(0),df['date_left'],df['date'])).drop('date_left',1)



  order_id       date
0       123 2020-01-02
1       456 2021-01-01
2       789 2020-10-11
3       135 2020-06-01

【讨论】:

  • 抱歉,我刚刚进行了编辑,当两个数据帧之间的 NaT 保持不变时,是否会考虑此解决方案?如果您查看我的上次编辑,您会发现我添加了 order_id 234,111 这些不应该继承 new_df @wwnde
  • 可以编辑答案。这将需要彻底改变方法。我们需要合并
  • 我很抱歉,我意识到我的例子并不完整,但这正是我想要完成的。我非常感谢这里的洞察力!
  • 谢谢,我一会儿就看这里。
【解决方案2】:

您可以merge,仅将那些可能已更新的订单子集,然后检查日期是否较晚,或者如果它为空然后填充,并使用它来子集合并的结果。

df_1['date'] = pd.to_datetime(df_1['date'])
df_2['date'] = pd.to_datetime(df_2['date'])

res = df_1.merge(df_2, on='order_id', suffixes=['_orig', ''])
#   order_id  date_orig       date
#0       123 2020-01-01 2020-01-02
#1       456        NaT 2021-01-01
#2       789 2020-10-10 2020-10-11
#3       135 2020-05-31 2020-06-01

m = res['date'].gt(res['date_orig']) | (res['date_orig'].isnull() & res['date'].notnull())
res.loc[m, ['order_id', 'date']]

   order_id       date
0       123 2020-01-02
1       456 2021-01-01
2       789 2020-10-11
3       135 2020-06-01

【讨论】:

  • 这个解决方案和@wwbde 之前的解决方案一样有效。谢谢!
猜你喜欢
  • 2013-05-29
  • 2016-11-25
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 2023-03-24
  • 2019-12-26
相关资源
最近更新 更多