从numpy.timedelta64值中提取天数


86

我正在使用pandas / python,我有两个日期时间序列s1和s2,它们是使用包含日期/时间的df字段上的“ to_datetime”函数生成的。

当我从s2减去s1

s3 = s2-s1

我得到一个类型为s3的系列

timedelta64 [ns]

0    385 days, 04:10:36
1     57 days, 22:54:00
2    642 days, 21:15:23
3    615 days, 00:55:44
4    160 days, 22:13:35
5    196 days, 23:06:49
6     23 days, 22:57:17
7      2 days, 22:17:31
8    622 days, 01:29:25
9     79 days, 20:15:14
10    23 days, 22:46:51
11   268 days, 19:23:04
12                  NaT
13                  NaT
14   583 days, 03:40:39

我如何看待该系列的1个元素:

s3 [10]

我得到这样的东西:

numpy.timedelta64(2069211000000000,'ns')

如何从s3中提取天数,并可能将其保留为整数(对小时/分钟等不太感兴趣)?

在此先感谢您的帮助。


4
仅供参考,即将合并到熊猫中以掌握此功能:github.com/pydata/pandas/pull/4534(您可以在0.12之前执行此操作,方法是:s.apply(lambda x: x / np.timedelta64(1,'D'))
Jeff

Answers:


145

您可以将其转换为具有日精度的timedelta。要提取天的整数值,可以将其除以一天的时间增量。

>>> x = np.timedelta64(2069211000000000, 'ns')
>>> days = x.astype('timedelta64[D]')
>>> days / np.timedelta64(1, 'D')
23

或者,如@PhillipCloud建议,只是days.astype(int)因为timedelta仅仅是一个64位整数,根据你所传递的第二个参数被解释以各种方式('D''ns',...)。

您可以在这里找到更多有关它的信息


16
你也可以做days.item().daysdays.astype(int)
菲利普·

1
较新的熊猫版本支持完整的Timedelta类型,请参见此处的文档:pandas.pydata.org/pandas-docs/stable/timedeltas.html
Jeff

这是.apply的良好候选人。您可以在计算列值的同一行中执行此操作,方法是将.apply(lambda x:x / np.timedelta64(1,'D'))放在最后,以将转换应用于列级。例如s3 =(s1-s2).apply(lambda x:x / np.timedelta64(1,'D'))。
Ezekiel Kruglick 2015年

2
对于4,000,000行,此方法astype('timedelta64[D]')(约96ms)比dt.days.(约24s)效率高得多。
赵鹏举

37

使用dt.days获得的日子属性为整数。

例如:

In [14]: s = pd.Series(pd.timedelta_range(start='1 days', end='12 days', freq='3000T'))

In [15]: s
Out[15]: 
0    1 days 00:00:00
1    3 days 02:00:00
2    5 days 04:00:00
3    7 days 06:00:00
4    9 days 08:00:00
5   11 days 10:00:00
dtype: timedelta64[ns]

In [16]: s.dt.days
Out[16]: 
0     1
1     3
2     5
3     7
4     9
5    11
dtype: int64

更一般而言-您可以使用.components属性访问的简化形式timedelta

In [17]: s.dt.components
Out[17]: 
   days  hours  minutes  seconds  milliseconds  microseconds  nanoseconds
0     1      0        0        0             0             0            0
1     3      2        0        0             0             0            0
2     5      4        0        0             0             0            0
3     7      6        0        0             0             0            0
4     9      8        0        0             0             0            0
5    11     10        0        0             0             0            0

现在,获取hours属性:

In [23]: s.dt.components.hours
Out[23]: 
0     0
1     2
2     4
3     6
4     8
5    10
Name: hours, dtype: int64

+1-这是目前执行此操作的最佳方法,因为自提出此问题以来熊猫包已取得进展。
奥斯丁,

7

假设您有一个timedelta系列:

import pandas as pd
from datetime import datetime
z = pd.DataFrame({'a':[datetime.strptime('20150101', '%Y%m%d')],'b':[datetime.strptime('20140601', '%Y%m%d')]})

td_series = (z['a'] - z['b'])

转换此timedelta列或序列的一种方法是将其强制转换为Timedelta对象(pandas 0.15.0+),然后从该对象中提取日期:

td_series.astype(pd.Timedelta).apply(lambda l: l.days)

另一种方法是将系列转换为以天为单位的timedelta64,然后将其转换为int:

td_series.astype('timedelta64[D]').astype(int)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.