大熊猫六个月的日期范围

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 是他们填写问题的数次。

但我想做什么:?

我的目标是从DiagnosisDateevery six month 返回,并将其标记到as the first 6 month record 的列上。在列中我们应该保存哪个六个月(前六​​个月,第二个月,第三个月,...)。

例如对于这个数据框,DiagnosisDatePatientNumber=12018-05-03 所以它应该从那个时候返回 6 monththe first 6 month2017-27-11 作为最大的AnswerDate 不属于该日期,它不会被标记为first six month。 如果第一个answerdate 在此日期以内,则将其标记为first 6 month

所以这里PatientNumber=16month 列中得到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 个月前的同一天不包含在此时期。这是关于间隔和界限的事情(希望它更清楚......)

以上是关于大熊猫六个月的日期范围的主要内容,如果未能解决你的问题,请参考以下文章

如何在SQL中获取当前日期最近六个月的前一个月数据

大熊猫在grouby之后按日期时间过滤

如何在日期选择器中设置 3 个月的日期范围?

如何从当前日期 PHP 获取最近 7 周、7 个月的日期范围?

从估算日期开始每个唯一用户的前六个月数据 - PostgreSQL

如何根据 Power BI 报表中选定的月份筛选器在 MDX 查询中显示最近六个月的数据(每个月一行)?