python - 如何根据两个不同列的日期获取交叉连接表的唯一记录?
问题描述
我有一个相当复杂的逻辑要创建。我有一些客户诊所遇到的数据,这些数据具有历史测试结果R_DATE_TESTED
,R_RESULT
映射到每个客户(P_CLIENT_ID
)P_DATE_ENCOUNTER
。
RECORD_ID | P_CLIENT_ID | R_CLIENT_ID | P_DATE_ENCOUNTER | R_DATE_TESTED | R_RESULT |
---|---|---|---|---|---|
302950 | 25835 | 25835.0 | 2016-12-21 | 2017-03-07 | 20.0 |
302951 | 25835 | 25835.0 | 2016-12-21 | 2017-08-03 | 20.0 |
302952 | 25835 | 25835.0 | 2016-12-21 | 2018-03-23 | 20.0 |
302953 | 25835 | 25835.0 | 2016-12-21 | 2019-06-28 | 20.0 |
302954 | 25835 | 25835.0 | 2016-12-21 | 2019-08-19 | 42.0 |
302955 | 25835 | 25835.0 | 2016-12-21 | 2020-04-20 | 40.0 |
302956 | 25835 | 25835.0 | 2016-12-21 | 2021-06-03 | 20.0 |
302957 | 25835 | 25835.0 | 2017-02-21 | 2017-03-07 | 20.0 |
302958 | 25835 | 25835.0 | 2017-02-21 | 2017-08-03 | 20.0 |
302959 | 25835 | 25835.0 | 2017-02-21 | 2018-03-23 | 20.0 |
302960 | 25835 | 25835.0 | 2017-02-21 | 2019-06-28 | 20.0 |
302961 | 25835 | 25835.0 | 2017-02-21 | 2019-08-19 | 42.0 |
302962 | 25835 | 25835.0 | 2017-02-21 | 2020-04-20 | 40.0 |
302963 | 25835 | 25835.0 | 2017-02-21 | 2021-06-03 | 20.0 |
302964 | 25835 | 25835.0 | 2017-04-25 | 2017-03-07 | 20.0 |
302965 | 25835 | 25835.0 | 2017-04-25 | 2017-08-03 | 20.0 |
302966 | 25835 | 25835.0 | 2017-04-25 | 2018-03-23 | 20.0 |
302967 | 25835 | 25835.0 | 2017-04-25 | 2019-06-28 | 20.0 |
302968 | 25835 | 25835.0 | 2017-04-25 | 2019-08-19 | 42.0 |
302969 | 25835 | 25835.0 | 2017-04-25 | 2020-04-20 | 40.0 |
302970 | 25835 | 25835.0 | 2017-04-25 | 2021-06-03 | 20.0 |
302971 | 25835 | 25835.0 | 2017-06-21 | 2017-03-07 | 20.0 |
302972 | 25835 | 25835.0 | 2017-06-21 | 2017-08-03 | 20.0 |
302973 | 25835 | 25835.0 | 2017-06-21 | 2018-03-23 | 20.0 |
302974 | 25835 | 25835.0 | 2017-06-21 | 2019-06-28 | 20.0 |
302975 | 25835 | 25835.0 | 2017-06-21 | 2019-08-19 | 42.0 |
302976 | 25835 | 25835.0 | 2017-06-21 | 2020-04-20 | 40.0 |
302977 | 25835 | 25835.0 | 2017-06-21 | 2021-06-03 | 20.0 |
302978 | 25835 | 25835.0 | 2017-09-04 | 2017-03-07 | 20.0 |
302979 | 25835 | 25835.0 | 2017-09-04 | 2017-08-03 | 20.0 |
302980 | 25835 | 25835.0 | 2017-09-04 | 2018-03-23 | 20.0 |
302981 | 25835 | 25835.0 | 2017-09-04 | 2019-06-28 | 20.0 |
302982 | 25835 | 25835.0 | 2017-09-04 | 2019-08-19 | 42.0 |
302983 | 25835 | 25835.0 | 2017-09-04 | 2020-04-20 | 40.0 |
302984 | 25835 | 25835.0 | 2017-09-04 | 2021-06-03 | 20.0 |
302985 | 25835 | 25835.0 | 2018-01-08 | 2017-03-07 | 20.0 |
302986 | 25835 | 25835.0 | 2018-01-08 | 2017-08-03 | 20.0 |
302987 | 25835 | 25835.0 | 2018-01-08 | 2018-03-23 | 20.0 |
302988 | 25835 | 25835.0 | 2018-01-08 | 2019-06-28 | 20.0 |
302989 | 25835 | 25835.0 | 2018-01-08 | 2019-08-19 | 42.0 |
302990 | 25835 | 25835.0 | 2018-01-08 | 2020-04-20 | 40.0 |
302991 | 25835 | 25835.0 | 2018-01-08 | 2021-06-03 | 20.0 |
302992 | 25835 | 25835.0 | 2018-04-03 | 2017-03-07 | 20.0 |
302993 | 25835 | 25835.0 | 2018-04-03 | 2017-08-03 | 20.0 |
302994 | 25835 | 25835.0 | 2018-04-03 | 2018-03-23 | 20.0 |
302995 | 25835 | 25835.0 | 2018-04-03 | 2019-06-28 | 20.0 |
302996 | 25835 | 25835.0 | 2018-04-03 | 2019-08-19 | 42.0 |
302997 | 25835 | 25835.0 | 2018-04-03 | 2020-04-20 | 40.0 |
302998 | 25835 | 25835.0 | 2018-04-03 | 2021-06-03 | 20.0 |
302999 | 25835 | 25835.0 | 2018-07-25 | 2017-03-07 | 20.0 |
303000 | 25835 | 25835.0 | 2018-07-25 | 2017-08-03 | 20.0 |
303001 | 25835 | 25835.0 | 2018-07-25 | 2018-03-23 | 20.0 |
303002 | 25835 | 25835.0 | 2018-07-25 | 2019-06-28 | 20.0 |
303003 | 25835 | 25835.0 | 2018-07-25 | 2019-08-19 | 42.0 |
303004 | 25835 | 25835.0 | 2018-07-25 | 2020-04-20 | 40.0 |
303005 | 25835 | 25835.0 | 2018-07-25 | 2021-06-03 | 20.0 |
数据已经排序。如何获取每个客户遇到(组P_CLIENT_ID AND P_DATE_ENCOUNTER
) 的唯一记录R_DATE_TESTED < R_DATE_ENCOUNTER
(但最近一次)。而且如果R_DATE_TESTED < R_DATE_ENCOUNTER
不是真的;它返回空值
逻辑结果应该如下:
P_CLIENT_ID | R_CLIENT_ID | P_DATE_ENCOUNTER | R_DATE_TESTED | R_RESULT |
---|---|---|---|---|
25835 | 25835.0 | 2016-12-21 | 钠 | 钠 |
25835 | 25835.0 | 2017-02-21 | 钠 | 钠 |
25835 | 25835.0 | 2017-04-25 | 2017-03-07 | 20.0 |
25835 | 25835.0 | 2017-06-21 | 2017-03-07 | 20.0 |
25835 | 25835.0 | 2017-09-04 | 2017-08-03 | 20.0 |
25835 | 25835.0 | 2018-01-08 | 2017-08-03 | 20.0 |
25835 | 25835.0 | 2018-04-03 | 2018-03-23 | 20.0 |
这个想法是,对于 each P_CLIENT_ID
,每个P_ENCOUNTER_ID
都返回它最近的前一个R_RESULT
(相遇之前的最新结果)。如果 CLIENT 没有在 之前的结果P_DATE_ENCOUNTER
,即 ( R_DATE_TESTED
is not < P_DATE_ENCOUNTERED
),那么它将为这些列返回空值(如前两条记录所示)。我想也许是在分区上使用一些排名的组合,.ffill()
但真的被卡住了。
解决方案
Yuo 可以使用以下代码:
import numpy as np
# df - your DataFrame
group = df.groupby(['P_CLIENT_ID', 'P_DATE_ENCOUNTER'])
def foo(df):
result = df.loc[df.P_DATE_ENCOUNTER>df.R_DATE_TESTED, ['R_DATE_TESTED', 'R_RESULT']].tail(1).reset_index()
if not result.empty:
return result
else:
return pd.DataFrame([[np.nan, np.nan, np.nan]], columns=['RECORD_ID','R_DATE_TESTED', 'R_RESULT'])
group.apply(foo)
推荐阅读
- javascript - 迭代定义为 Promise 的嵌套对象数组
- magento2 - Magento 2 - 用于混合的混合
- django-models - Django:如何在模型的 clean 方法中获取动态添加的表单字段
- python-3.x - 在 csv 文件中单独提取每个数据
- javascript - 如何让递归树视图工作AngularJs
- python - 参与区 Nao
- microsoft-graph-api - 使用 Grap Api 返回用户服务详细信息(OneDrive for Business、Outlook Online、Sharepoint Online、日历)
- sql-server - 在 T-SQL 中使用它在 UNION 中转换时 CAST 失败
- javascript - 如何调用另一个页面,运行 javascript 以收集城市名称和邮政编码,并以城市名称和邮政编码作为参数返回上一页
- ios - Unity 中的 Firebase 身份验证拒绝“使用 Apple 登录”令牌