Pandas 熊猫六个月的日期范围

Pandas 熊猫六个月的日期范围,pandas,dataframe,group-by,time-series,data-analysis,Pandas,Dataframe,Group By,Time Series,Data Analysis,这是我的数据框 PatientNumber QT Answer Answerdate DiagnosisDate 1 1 transferring No 2017-03-03 2018-05-03 2 1 preparing food No 2017-03-03 2018-05-03 3 1 medicat

这是我的数据框

PatientNumber           QT         Answer   Answerdate  DiagnosisDate 
1        1          transferring     No      2017-03-03 2018-05-03     
2        1          preparing food   No      2017-03-03 2018-05-03     
3        1          medications      Yes     2017-03-03 2018-05-03     
4        2          transferring     No      2011-05-10 2012-05-04       
5        2          preparing food   No      2011-05-10 2012-05-04     
6        2          medications      No      2011-05-10 2012-05-04     
7        2          transferring     Yes     2011-15-03  2012-05-04     
8        2          preparing food   Yes     2011-15-03  2012-05-04     
9        2          medications      No      2011-15-03  2012-05-04     
10       2          transferring     Yes     2010-15-12 2012-05-04     
11       2          preparing food   No      2010-15-12 2012-05-04     
12       2          medications      No      2010-15-12 2012-05-04     
13       2          transferring     Yes     2009-10-10 2012-05-04     
14       2          preparing food   No      2009-10-10 2012-05-04     
15       2          medications      No      2009-10-10 2012-05-04     
16       3          medications      No      2008-10-10 2010-07-04     
我刚刚发现了一个与我的问题相关的链接,它没有得到任何正确的答案

一些解释: 对于每个患者编号,诊断日期是唯一的。回答日期是他们填写问题的几次

但我想做的是:

我的目标是每六个月回顾一次诊断数据,并将其标记在
列中,作为前六个月的记录。在专栏中,我们应该保存哪六个月(前六个月、第二个月、第三个月……)

例如,对于此数据帧,
PatientNumber=1的
DiagnosisDate
2018-05-03
,因此它应该从该时间返回
6个月
前6个月
2017-27-11
因为最大回答日期不在该日期之下,所以不会标记为
前6个月
。 如果第一个
应答日期
在该日期之下,它将被标记为
前6个月

所以这里的
PatientNumber=1
6month
列中得到了
3
,因为当我们从
diagnostisdate
6month
返回时,
answerdate
将在随后的
6month
列中。 因此,此数据帧的输出将为:

PatientNumber           QT         Answer   Answerdate  DiagnosisDate  6month
1        1          transferring     No      2017-03-03 2018-05-03     3
2        1          preparing food   No      2017-03-03 2018-05-03     3
3        1          medications      Yes     2017-03-03 2018-05-03     3
4        2          transferring     No      2011-05-10 2012-05-04     1 
5        2          preparing food   No      2011-05-10 2012-05-04     1
6        2          medications      No      2011-05-10 2012-05-04     1
7        2          transferring     Yes     2011-15-04  2012-05-04    2
8        2          preparing food   Yes     2011-15-04  2012-05-04    2
9        2          medications      No      2011-15-04  2012-05-04    2
10       2          transferring     Yes     2010-15-12 2012-05-04     3
11       2          preparing food   No      2010-15-12 2012-05-04     3
12       2          medications      No      2010-15-12 2012-05-04     3
13       2          transferring     Yes     2009-10-10 2012-05-04     5
14       2          preparing food   No      2009-10-10 2012-05-04     5
15       2          medications      No      2009-10-10 2012-05-04     5
16       3          medications      No      2008-10-10 2010-07-04     4
对于PatientNumber=2,它将从
DiagnosisDate=2012-05-04开始,然后返回6个月。它将是
2011-11-04

我应用了这个:

data['6month'] = pd.date_range(end=data['diagnosisdate'],periods=2, freq='6M',closed='left')
首先它只关心月份,所以近似计算不准确, 我找不到一种方法来提到6个月的数字,就像我在上面的数据框中提到的一样(在6个月一栏中,我指的是12,…而不是日期)

因此,根据数据,我们可以在
6个月
列中看到
1…10
中的数字(考虑到诊断前5年)

说来话长。希望有人能抽出时间:)


另外,我需要保持整个专栏的结果不变。

这并不是你想要的,而是一个提供足够好结果的方法。我认为您可以通过计算列diagnostisdate和Answerdate之间的时间差,然后除以pd.np.timedelta64(6,'M')
(将频率更改为6个月)。然后需要使用
ceil
函数来获取上面的整数,例如:

data['6month'] = (pd.np.ceil((data['DiagnosisDate']-pd.Timedelta(days=1)-data['Answerdate'])
                                             /pd.np.timedelta64(6, 'M')).astype(int))
要忽略负列,请执行以下操作:

data = data[(data['6month'] >= 0)]
根据您的样本,它给出:

    PatientNumber            QT Answer Answerdate DiagnosisDate  6month
1               1  transferring     No 2017-03-03    2018-03-05       3
2               1     preparing     No 2017-03-03    2018-03-05       3
3               1   medications    Yes 2017-03-03    2018-03-05       3
4               2  transferring     No 2011-10-05    2012-04-05       1
5               2     preparing     No 2011-10-05    2012-04-05       1
6               2   medications     No 2011-10-05    2012-04-05       1
7               2  transferring    Yes 2011-03-15    2012-04-05       3
8               2     preparing    Yes 2011-03-15    2012-04-05       3
9               2   medications     No 2011-03-15    2012-04-05       3
10              2  transferring    Yes 2010-12-15    2012-04-05       3
11              2     preparing     No 2010-12-15    2012-04-05       3
12              2   medications     No 2010-12-15    2012-04-05       3
13              2  transferring    Yes 2009-10-10    2012-04-05       5
14              2     preparing     No 2009-10-10    2012-04-05       5
15              2   medications     No 2009-10-10    2012-04-05       5
16              3   medications     No 2008-10-10    2010-04-07       3
另外,我不会使用
pd.date\u range
,因为它看起来不像您想要的那样,但我可能错了


编辑:若要删除DiagnostisDate在Answerdate之前的情况,一旦您创建了6个月的列,只需执行
data=data[data['6months']>0]
,因为在这种情况下,值将为负值或零

Hi Saria请与我们分享您的
df.to_dict()
这样我们可以复制。你的意思是说
6个月
应该是
diagnosis\u date
-6个月吗?@user32185谢谢你的提问,但你的意思是什么,因为我已经分享了一个数据帧示例,我认为这就足够了。请告诉我还需要什么?@ifly6谢谢你的询问。我的目标是每6个月分析患者的回答。因此,从诊断日期,我必须考虑他们的答案,每6个月。以后我会每6个月做一些分析。请让我知道哪个部分仍然模棱两可。thanks@ifly6我添加了一些说明,并解释了PatientNumber 1输出中的数字。希望它更清楚:)非常感谢您的时间,那么为什么不使用熊猫的功能,这有利于与时间一起工作呢?其实这对我没有帮助,6个月的数字很重要,它帮助我在生病前每6个月分析一次患者的答案。这样做大约会在以后产生错误的结果。我相信我们可以在熊猫中使用时间序列函数,就像我上面分享的一样。不管怎样,谢谢你抽出时间,如果你有广告,请告诉我idea@sariaGoudarzi复制您的数据时遇到问题,因此我编辑了结果。我理解你为什么不想要错误的号码,但我相信这个解决方案会有很好的效果。如果您想使用
pd.date\u range
,我认为您应该考虑执行类似
data.apply(lambda行:len(pd.date\u range(start=row['Answerdate'],end=row['DiagnosisDate'],freq='6M',closed='left'))的操作,1)
但是,至少在您的示例中,您会得到相同的结果:)我不太感谢以下内容,看来我把日期和月份复制错了,请几分钟后检查问题中的数据场。也许您使用更新后的数据帧的方式会给出所需的输出现在数据帧中的日期顺序是年/日/月,您可以在更新后的数据帧上应用代码吗?@sariaGoudarzi pd.Timedelta(天=1)是一天。为了考虑,如你所想,对于第一排第1号患者,你需要说6个月的回顾期从前一天开始,否则,6个月前的同一天不在这个时期。这是一个关于间隔和界限的问题(希望它更清楚……)