Python PANDAS TimeGrouper具有个性化的下采样起点

Python PANDAS TimeGrouper具有个性化的下采样起点,python,datetime,pandas,Python,Datetime,Pandas,TL:DR 我想按主题和30天的时间段分组,但30天的时间段并不是按主题个性化的 最好的处理方法是什么 完整解释 我有一个参与者的样本,他们都在不同的时间开始了一项科学研究。我想使用TimeGrouper在研究的第一天之后,按照每30天的时间段进行分段 经过一些搜索之后,这似乎是不可能的,因为很难指定TimeGrouper的起点。因此,作为代理,我可以为每个人使用第一个观察到的时间戳 为此,我尝试按参与者ID和TimeGrouper进行分组,但30天的时间段似乎从最早的全局时间点开始计算,而不是

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)
上述代码应创建此数据框:

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

fakedf.groupby(['participantID', pd.TimeGrouper(freq="30D",  closed='left')]).count()
以下是输出:

您可以看到SubC1和SubC2在2015-06-25开始进行时间分组,尽管SubC2直到2015-07-25才有真正的时间戳

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

a) 研究开始日期,或

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

我有一个低技术的解决方案,我知道会奏效,但我希望有一个好的,优雅的TimeGrouper解决方案


提前谢谢

要使
TimeGrouper
处于参与者级别,首先在
'participantID'
上执行
groupby
,然后在每个组内,在
TimeGrouper
上执行另一个
groupby
。为了清楚起见,我将第二个
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
您不需要为
TimeGrouper
指定
键。默认情况下,我相信它将使用索引。但是,如果希望
时间分组
位于其他列之上,如
'studystart'
,则可以通过
参数传递它:

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

你,我的朋友。你太棒了。请克隆你自己。