按最接近日期合并数据框

3

我有一些实验数据,以受试者ID和日期为索引。我希望将这些数据合并在一起,但是受试者可能在不同的日期进行实验。以下是两个不同实验结果的示例:

SubjectID  Date        ScoreA
1          2016-09-20      10
1          2016-09-21      12
1          2016-12-01      11

SubjectID  Date        ScoreB
1          2016-09-20      1
1          2016-09-24      5
1          2016-11-28      3
1          2016-12-11      9

我希望将行连接到最近可用的日期。因此,理想情况下,我的期望输出是

SubjectID   Date1         Date2        ScoreA ScoreB
1            2016-09-20    2016-09-20    10      1
1            2016-09-21    2016-09-24    12      5
1            2016-12-01    2016-11-28    11      3

请注意,“最接近日期”是绝对值最接近的日期。我该如何实现类似的功能?

如果有两个与ScoreA日期相同距离的ScoreB日期,那么期望的结果是什么?例如: ScoreA日期为9/24, ScoreB日期为9/22和9/26?或者这种情况保证永远不会发生? - B. Shieh
@B.Shieh 这并不是有保证的。在这种情况下,我更喜欢较早的日期。 - Demetri Pananos
在你的例子中,如果2016-09-20更接近于2016-09-21,为什么Date1=2016-09-21与Date2=2016-09-24相关联? - foglerit
@foglerit 哦,好发现,那只是我的疏忽。 - Demetri Pananos
关于fogelrit的catch。这意味着2016-09-20的相同ScoreB将与2016-09-20和2016-09-21的两个不同的ScoreA相关联。这是期望的结果吗?另一种澄清的方法:Date1和ScoreA应该是基础数据集(例如不可变),然后取最接近每个Date1/ScoreA的Date2/ScoreB?还是应该给予Date1/ScoreA和Date2/ScoreB相等的优先权?在这种情况下,你的例子应该怎么做? - B. Shieh
2
我没有使用过它,但也许你可以看一下pandas.merge_asof。也许尝试按日期合并并按SubjectID分组?http://pandas.pydata.org/pandas-docs/version/0.19.0/generated/pandas.merge_asof.html - user3582076
1个回答

2

我不知道是否有一种使用默认的pandas功能来实现您想要的方法,但使用自定义聚合函数可以很容易地实现它:

def pick_closest(g):
    closest_date_loc = (g.Date1 - g.Date2).abs().argmin()
    return g.loc[closest_date_loc, ['ScoreA','Date2','ScoreB']]

merged = df1.merge(df2, on='SubjectID', suffixes=['1', '2'])
df3  = merged.groupby(['SubjectID','Date1'], as_index=False).apply(pick_closest).reset_index()
df3

   SubjectID      Date1  ScoreA      Date2  ScoreB
0          1 2016-09-20      10 2016-09-20       1
1          1 2016-09-21      12 2016-09-20       1
2          1 2016-12-01      11 2016-11-28       3

在这段代码片段中,最初是在SubjectID上合并两个框架,生成所有Date1Date2的可能组合。然后pick_closest函数为每个SubjectID/Date1组选择日期差异最小的Date1Date2行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接