Pandas Timedelta 以天为单位

Posted

技术标签:

【中文标题】Pandas Timedelta 以天为单位【英文标题】:Pandas Timedelta in Days 【发布时间】:2013-04-12 18:22:02 【问题描述】:

我在 pandas 中有一个名为“munged_data”的数据框,其中包含两列“entry_date”和“dob”,我已使用 pd.to_timestamp 将其转换为时间戳。我试图弄清楚如何根据时间计算人的年龄'entry_date' 和 'dob' 之间的区别,要做到这一点,我需要得到两列之间的天数差异(这样我就可以像 round(days/365.25) 一样做一些事情。我似乎无法找到一种使用矢量化操作的方法。当我执行 munged_data.entry_date-munged_data.dob 时,我得到以下信息:

internal_quote_id
2                    15685977 days, 23:54:30.457856
3                    11651985 days, 23:49:15.359744
4                     9491988 days, 23:39:55.621376
7                     11907004 days, 0:10:30.196224
9                    15282164 days, 23:30:30.196224
15                  15282227 days, 23:50:40.261632  

但是我似乎无法将天数提取为整数,以便我可以继续计算。 任何帮助表示赞赏。

【问题讨论】:

TLDR:(df['entry_date'] - df['dob']).dt.days(见下面我的回答) 【参考方案1】:

使用自 v0.15.0 起可用的 Pandas 类型 Timedelta,您也可以这样做:

In[1]: import pandas as pd
In[2]: df = pd.DataFrame([ pd.Timestamp('20150111'), 
                           pd.Timestamp('20150301') ], columns=['date'])
In[3]: df['today'] = pd.Timestamp('20150315')
In[4]: df
Out[4]: 
        date      today
0 2015-01-11 2015-03-15
1 2015-03-01 2015-03-15

In[5]: (df['today'] - df['date']).dt.days
Out[5]: 
0    63
1    14
dtype: int64

【讨论】:

太棒了!我认为这应该是公认的答案。 Timedelta.dt.daysapply(lambda x: x.days()) 快 100 倍 说真的,为什么这不是公认的答案?【参考方案2】:

你需要 0.11 (0.11rc1 已经出来了,下周最后的问题)

In [9]: df = DataFrame([ Timestamp('20010101'), Timestamp('20040601') ])

In [10]: df
Out[10]: 
                    0
0 2001-01-01 00:00:00
1 2004-06-01 00:00:00

In [11]: df = DataFrame([ Timestamp('20010101'), 
                          Timestamp('20040601') ],columns=['age'])

In [12]: df
Out[12]: 
                  age
0 2001-01-01 00:00:00
1 2004-06-01 00:00:00

In [13]: df['today'] = Timestamp('20130419')

In [14]: df['diff'] = df['today']-df['age']

In [16]: df['years'] = df['diff'].apply(lambda x: float(x.item().days)/365)

In [17]: df
Out[17]: 
                  age               today                diff      years
0 2001-01-01 00:00:00 2013-04-19 00:00:00 4491 days, 00:00:00  12.304110
1 2004-06-01 00:00:00 2013-04-19 00:00:00 3244 days, 00:00:00   8.887671

最后你需要这个奇怪的应用程序,因为还没有完全支持 timedelta64[ns] 标量(例如,我们现在如何使用时间戳来处理 datetime64[ns],在 0.12 中)

【讨论】:

感谢 Jeff 非常有帮助,我不知道 item() 方法。我设法用 0.10 太棒了!这是一些食谱和新文档的链接(在 0.11 中),pandas.pydata.org/pandas-docs/dev/cookbook.html#miscellaneous 您不需要这种需要特定熊猫版本的方法。相反,请遵循@dant (df['entry_date'] - df['dob']).dt.days 的建议【参考方案3】:

不确定你是否还需要它,但在 Pandas 0.14 中我通常使用 .astype('timedelta64[X]') 方法 http://pandas.pydata.org/pandas-docs/stable/timeseries.html(变频)

df = pd.DataFrame([ pd.Timestamp('20010101'), pd.Timestamp('20040605') ])
df.ix[0]-df.ix[1]

返回:

0   -1251 days
dtype: timedelta64[ns]
(df.ix[0]-df.ix[1]).astype('timedelta64[Y]')

返回:

  0   -4
 dtype: float64

希望对你有所帮助

【讨论】:

我刚刚搜索了一下,发现了这个问题。我的问题是我对我的数据框使用了类似于 Jeff 的答案。但是,我有一百万行,所以应用有点慢。使用.astype('timedelta64[D]') 是一种更快的方法(大约 200 倍)【参考方案4】:

让我们指定您有一个名为 time_difference 的 pandas 系列,其类型为 numpy.timedelta64[ns]

仅提取日期(或任何所需属性)的一种方法如下:

just_day = time_difference.apply(lambda x: pd.tslib.Timedelta(x).days)

使用此函数是因为 numpy.timedelta64 对象没有“天”属性。

【讨论】:

【参考方案5】:

要将任何类型的数据转换为天,只需使用 Timedelta().days:

pd.Timedelta(1985, unit='Y').days
84494

【讨论】:

以上是关于Pandas Timedelta 以天为单位的主要内容,如果未能解决你的问题,请参考以下文章

以天为单位计算用户的年龄java [重复]

Android/Java - 以天为单位的日期差异

如何以天为单位注释日期时间的差异

使用PHP的日期差(以天为单位)

以天为单位的日期时间差异的高性能计算

FLINK 基于1.15.2的Java开发-使用AggregateFunction解决以天为单位诸如PVUV等统计的实时计算