![](/img/trans.png)
[英]Comparing Pandas Dataframe Rows & Dropping rows with overlapping dates
[英]Pandas selecting rows in a second dataframe based on overlapping dates in the first dataframe?
我有一份超过 50 万人的名单。 数据看起来像第一个表。 我想使用第一张表中的录取日期,如果第二张表中同一个人的录取日期在第一张表中录取日期的 30 天内,那么我想将该重叠记录存储在第三张桌子。 我想要的示例如下。 有没有比使用第一个表中的 person_ids 和日期并检查第二个表中的每一行的 iterrows 更快的方法?
Table 1
| person_id | admission_date | value |
| 1234 | 2017-01-31 | 6 |
| 5678 | 2018-03-20 | 12 |
| 9101 | 2017-02-22 | 11 |
| 1234 | 2020-10-31 | 19 |
| 5678 | 2019-06-16 | 21 |
| 9101 | 2021-12-14 | 8 |
Table 2
| person_id | admission_date | value |
| 1234 | 2015-01-31 | 10 |
| 1234 | 2017-02-12 | 152 |
| 5678 | 2017-01-31 | 10 |
| 5678 | 2018-04-10 | 10 |
| 9101 | 2017-02-25 | 99 |
| 9101 | 2017-03-01 | 10 |
| 1234 | 2012-12-31 | 10 |
| 5678 | 2019-07-10 | 11 |
| 9101 | 2017-01-31 | 10 |
Table 3
| person_id | admission_date | value |
| 1234 | 2017-02-12 | 152 |
| 5678 | 2018-04-10 | 10 |
| 9101 | 2017-02-25 | 99 |
| 9101 | 2017-03-01 | 10 |
| 5678 | 2019-07-10 | 11 |
您需要使用merge_asof
:
df1['admission_date'] = pd.to_datetime(df1['admission_date'])
df2['admission_date'] = pd.to_datetime(df2['admission_date'])
out = (pd
.merge_asof(df1.sort_values(by='admission_date')
.rename(columns={'admission_date': 'date'})
.drop(columns='value'),
df2.sort_values(by='admission_date'),
by='person_id',
left_on='date',
right_on='admission_date',
direction='forward',
tolerance=pd.Timedelta('30D')
)
.drop(columns='date')
.dropna(subset='value')
)
output:
person_id admission_date value
0 1234 2017-02-12 152.0
1 9101 2017-02-25 99.0
2 5678 2018-04-10 10.0
3 5678 2019-07-10 11.0
设表 1 为 df1,表 2 为 df2,表 3 为 df3
不确定表 1 是否与表 2 一样具有重复的人员 ID,因此假设它在这里存在,并采用表 1 和表 2 的最近入场日期。
df1 = df1.sort_values(by=['person_id','admission_date'],ascending =False)
df1 = df1[df1['person_id'].duplicated()==False] % only has the latest admission for any person_id
df2 = df2.sort_values(by=['person_id','admission_date'],ascending =False)
df2 = df2[df2['person_id'].duplicated()==False] % only has the latest admission for any person_id
df3 = pd.concat([df1.set_index('person_id')['admission_date'].to_frame('adm_date_1'),df2.set_index('person_id')],axis=1,join='inner')
现在我们已经对齐了数据,我们可以检查 30 天的条件:
mask = (df3['adm_date_1']-df3['admission_date']).apply(lambda x: x.days).abs()
df3 = df3.loc[mask,['admission_date','value']]
为此,日期列需要是日期时间类型,如果不是,则首先需要进行转换
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.