大熊猫六个月的日期范围
Posted
技术标签:
【中文标题】大熊猫六个月的日期范围【英文标题】:date range for six monthly in pandas 【发布时间】:2018-11-24 12:13:38 【问题描述】:所以,这是我的数据框。
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
我刚刚找到一个与我的问题here 相关的链接,它没有得到任何正确答案。
一些解释: 对于每个患者编号,diagnosisDate 是唯一的。Answer Date 是他们填写问题的数次。
但我想做什么:?
我的目标是从DiagnosisDate
every six month
返回,并将其标记到as the first 6 month record
的列上。在列中我们应该保存哪个六个月(前六个月,第二个月,第三个月,...)。
例如对于这个数据框,DiagnosisDate
的 PatientNumber=1
是 2018-05-03
所以它应该从那个时候返回 6 month
。 the first 6 month
是2017-27-11
作为最大的AnswerDate 不属于该日期,它不会被标记为first six month
。
如果第一个answerdate
在此日期以内,则将其标记为first 6 month
。
所以这里PatientNumber=1
在6month
列中得到3
,因为当我们从diagnosisdate
6 month
返回时,answerdate
会在一段时间后落在6 month
之下。
所以这个数据框的输出将是:
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 月列中,我的意思是 1 2,...而不是日期。
因此根据数据,我们可以在6month
列中看到1...10
的数字(考虑到诊断前5年)
说来话长。希望有人能花点时间:)。
我还需要保持整个列的结果不变。
【问题讨论】:
嗨,Saria,请与我们分享您的df.to_dict()
,以便我们进行复制。
你的意思是说6month
应该是diagnosis_date
- 6个月?
@user32185 感谢您的提问,但是您的意思是什么,因为我已经分享了一个数据框样本,我认为这已经足够了。请让我知道还需要什么?
@ifly6 感谢您的提问。我的目标是每 6 个月分析一次患者的回答。所以从诊断日期开始,我必须每 6 个月考虑他们的答案。稍后我将对每 6 个月进行一些分析。请让我知道哪个部分仍然模棱两可。谢谢
@ifly6 我添加了一些说明,并解释了输出中的患者编号 1 的数字。希望它更清楚:)
【参考方案1】:
这并不完全是您想要的,但可以提供足够好的结果。我认为您可以通过计算列 DiagnosisDate 和 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_range
,因为它似乎不像你想要的那样,但我可能错了。
编辑:要删除 DiagnosisDate 在 Answerdate 之前的情况,一旦您创建了 6 个月的列,只需执行 data = data[data['6months'] > 0]
,因为在这种情况下该值将为负数或零
【讨论】:
非常感谢您抽出宝贵的时间,那么为什么不使用pandas 中适合与时间打交道的功能呢?实际上它对我没有帮助,6个月的数字很重要,它可以帮助我在生病前每六个月分析一次患者的答案。大约稍后会产生错误的结果。我相信我们可以像我上面分享的那样在 pandas 中使用时间序列函数。无论如何,感谢您抽出时间,如果您有任何想法,请告诉我 @sariaGoudarzi 我在复制您的数据时遇到了麻烦,所以我编辑了我的结果。我理解你为什么不想要错误的数字,但我相信这个解决方案会产生很好的效果。如果您想使用pd.date_range
,我认为您应该考虑执行类似data.apply(lambda row: len(pd.date_range(start=row['Answerdate'], end=row['DiagnosisDate'], freq='6M',closed='left')),1)
的操作,但至少在您的示例中,您会得到相同的结果:)
非常感谢您的关注,我似乎错误地复制了日期和月份,请几分钟后检查问题中的数据农场。也许您使用更新的数据框的方式可以提供所需的输出
现在数据框中日期的顺序是年/日/月,请问您可以在更新后的数据框中应用您的代码吗?
@sariaGoudarzi pd.Timedelta(days=1) 是一天。为了考虑,如您所愿,1 代表 2 号患者的第一行,您需要说您回顾的 6 个月期间从前一天开始,否则,6 个月前的同一天不包含在此时期。这是关于间隔和界限的事情(希望它更清楚......)以上是关于大熊猫六个月的日期范围的主要内容,如果未能解决你的问题,请参考以下文章
如何从当前日期 PHP 获取最近 7 周、7 个月的日期范围?