繁体   English   中英

Pandas 根据第一个 dataframe 中的重叠日期在第二个 dataframe 中选择行?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM