TL:DR

我想按主题和30天的时间段进行分组,但是30天的时间段不是按主题进行个性化设置的。

处理此问题的最佳方法是什么?

完整说明

我有一个参与者样本,他们都是在不同时间开始科学研究的。我想使用TimeGrouper在研究的第一天之后每30天细分一次。

经过一些搜索之后,似乎不可能实现,因为很难为TimeGrouper指定起点。因此,作为代理,我可以为每个人使用第一个观察到的时间戳。

为此,我尝试按参与者ID和TimeGrouper进行分组,但是30天的时间似乎从最早的全局时间点开始计算,而不是从每个参与者的最早时间点开始计算。

我知道这有点复杂,所以这里是一些代码:

这是一个伪数据框,代表我正在使用的数据类型:

fakedf = pd.DataFrame({'participantID':['subj1', 'subj1', 'subj1', 'subj1', 'subj2', 'subj2', 'subj2', 'subj2'],
                   'timestamp':['2015-06-25 01:12:00', '2015-06-30 11:02:00', '2015-07-05 09:33:00', '2015-07-28 07:22:00',
        '2015-07-25 01:11:00', '2015-07-31 11:02:00', '2015-08-07 09:33:00', '2015-08-10 07:22:00'], 'studystart':['2015-06-20 00:00:00', '2015-06-20 00:00:00', '2015-06-20 00:00:00', '2015-06-20 00:00:00',
        '2015-07-25 00:00:00', '2015-07-25 00:00:00', '2015-07-25 00:00:00', '2015-07-25 00:00:00']})

fakedf.index = pd.to_datetime(fakedf.timestamp)


上面的代码应创建此数据框:

python - PANDAS TimeGrouper具有个性化的下采样起点-LMLPHP

下面是我希望实际工作的代码:

fakedf.groupby(['participantID', pd.TimeGrouper(freq="30D",  closed='left')]).count()


这是输出:

python - PANDAS TimeGrouper具有个性化的下采样起点-LMLPHP

您可以看到subj1和subj2在2015-06-25开始它们的时间分组,尽管subj2直到2015-07-25才有真实的时间戳。

如果我可以通过以下任一方式开始每30天一次的时间分组,那我会很高兴:

a)研究开始日期,或

b)每个参与者的第一个时间戳

我有一个我知道可以使用的低技术解决方案,但是我希望有一个很好的,优雅的TimeGrouper解决方案。

提前致谢!

最佳答案

要使TimeGrouper处于参与者级别,请首先在groupby上执行'participantID',然后在每个组内,在groupby上执行另一个TimeGrouper。为了清楚起见,我将第二个groupby分离为一个单独的函数。

def inner_groupby(grp, key=None):
    return grp.groupby(pd.TimeGrouper(key=key, freq='30D')).count()

fakedf.groupby('participantID').apply(inner_groupby)


结果输出:

                                   participantID  studystart  timestamp
participantID timestamp
subj1         2015-06-25 01:12:00              3           3          3
              2015-07-25 01:12:00              1           1          1
subj2         2015-07-25 01:11:00              4           4          4


您无需为key指定TimeGrouper。默认情况下,我相信它将使用索引。但是,如果希望TimeGrouper位于其他列上,例如'studystart',则可以通过key参数传递它:

fakedf.groupby('participantID').apply(inner_groupby, key='studystart')


以及key='studystart'的结果输出:

                          participantID  timestamp
participantID studystart
subj1         2015-06-20              4          4
subj2         2015-07-25              4          4

关于python - PANDAS TimeGrouper具有个性化的下采样起点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37954489/

10-09 04:39