问题描述
我有以下两个数据框。
df_1:
order_id date
123 2020-01-01
456 NULL
789 2020-10-10
135 2020-05-31
df_2:
order_id date
123 2020-01-02
456 NULL
789 2020-10-10
135 2020-12-31
我希望在列表中收集所有 order_id,并在 df_2 中的日期大于 df_1 中的日期时更新 df_2['date']。
输出应该是对 df_1 的更新:
order_id date
123 2020-01-02
456 NULL
789 2020-10-10
135 2020-12-31
和一个带有 order_id[123,135] 的列表
在后续请求中,日期也有可能从 NaT 变为 date,例如 df_2 现在等于:
order_id date
123 2020-01-02
456 1999-01-01
789 2020-10-10
135 2020-12-31
246 NaT
468 NaT
因此 df_1 现在等于:
order_id date
123 2020-01-02
456 1999-01-01
789 2020-10-10
135 2020-12-31
而 order_ids 的列表将是 [123,456,135]
我的尝试:
if df_2['date'] > df_1['date']:
但我收到以下消息: ValueError:只能比较标记相同的系列对象
任何建议将不胜感激,谢谢!
解决方法
在比较之前,您需要在两个 DataFrame 中匹配值,此解决方案使用 Series.map
,DataFrame.merge
中的另一个左连接,然后通过 DataFrame.loc
设置值:
#convert to datetimes if necessary
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
print (df_1)
order_id date
0 123 2020-01-02
1 456 NaT
2 789 2020-10-10
3 135 2020-12-31
order_id = df_1.loc[mask,'order_id'].tolist()
print (order_id)
[123,135]
另一个想法:
df = df_1.merge(df_2,on='order_id',how='left',suffixes=('','_'))
mask = df['date_'] > df['date']
df.loc[mask,'date'] = df.pop('date_')
print (df)
order_id date
0 123 2020-01-02
1 456 NaT
2 789 2020-10-10
3 135 2020-12-31
order_id = df_1.loc[mask,135]