带有合并的熊猫merge_asof

时间:2019-10-21 05:32:50

标签: python pandas

我有2个数据框,如下所示。

admit = pd.DataFrame({"HN": ["001", "002", "001", "002"],
                      "dob": ["1999-05-25", "1979-08-12", "1999-05-25", "1979-08-12"],
                      "dateadm": ["2000-11-10", "2012-07-11", "2014-04-02", "2016-03-05"]})

admit["dateadm"] = pd.to_datetime(admit["dateadm"], format="%Y-%m-%d")

lab = pd.DataFrame({"HN": ["001", "002", "001", "002", "001"],
                    "labdate":["2000-11-11", "2012-07-13", "2000-11-15", "2016-03-05", "2014-04-02"],
                    "FPG": [100.0, 120.0, 95.5, 125.0, 99.0]})

lab["labdate"] = pd.to_datetime(lab["labdate"], format="%Y-%m-%d")
lab = lab.sort_values(by="labdate").reset_index(drop=True)

我想将入场时间和实验室合并在一起,以将任何实验室日期的FPG平均值取到最近的dateadm。基本上,任何dateadm的labdate应该与该dataadm相同或较晚。我能想到这个命令

data = pd.merge_asof(admit, lab, left_on="dateadm", right_on="labdate", by="HN", direction="forward")

我得到的返回结果如下。

 HN       dob        dateadm     labdate      FPG
001   1999-05-25   2000-11-10   2000-11-11   100.0
002   1979-08-12   2012-07-11   2012-07-13   120.0
001   1999-05-25   2014-04-02   2014-04-02    99.0
002   1979-08-12   2016-03-05   2016-03-05   125.0

但是,带有dateadm 2000-11-10的HN 001具有2个最接近的Labdate 2000-11-11和2000-11-15。因此,第一行的FPG值应为100.0到95.5之间的平均值,等于97.75。我认为我的命令只考虑了第一个最近的日期。我是否可以建议您像这样在第一行中获取具有正确FPG值的期望输出。

 HN       dob        dateadm     labdate      FPG
001   1999-05-25   2000-11-10   2000-11-11    97.75
002   1979-08-12   2012-07-11   2012-07-13   120.0
001   1999-05-25   2014-04-02   2014-04-02    99.0
002   1979-08-12   2016-03-05   2016-03-05   125.0

1 个答案:

答案 0 :(得分:0)

最后,我找到了解决问题的方法,只需交换左右表,然后按以下方式分组即可。

data = pd.merge_asof(lab, admit, left_on="labdate", right_on="dateadm", by="HN", direction="backward").groupby(["HN", "dob", "dateadm"]).agg({"FPG": "mean"}).reset_index()

由于一个dateadm可以具有多个labdate,但是我想要的数据粒度是通过HN和dateadm实现的。因此,我可以在所需的输出中忽略labdate。