【问题标题】:extracting days from a numpy.timedelta64 value从 numpy.timedelta64 值中提取天数
【发布时间】:2013-08-15 10:28:45
【问题描述】:

我正在使用 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 中提取天数并将它们保存为整数(对小时/分钟等不太感兴趣)?

提前感谢您的帮助。

【问题讨论】:

  • 仅供参考,即将合并到 pandas 掌握此功能:github.com/pydata/pandas/pull/4534(您可以在 0.12 及之前通过:s.apply(lambda x: x / np.timedelta64(1,'D'))

标签: python numpy pandas


【解决方案1】:

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

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

或者,正如@PhillipCloud 建议的那样,只是days.astype(int),因为timedelta 只是一个64 位整数,根据您传入的第二个参数('D''ns'、... )。

您可以在here找到更多相关信息。

【讨论】:

  • 你也可以days.item().daysdays.astype(int)
  • 更多最新版本的 pandas 支持完整的 Timedelta 类型,请参阅此处的文档:pandas.pydata.org/pandas-docs/stable/timedeltas.html
  • 这是 .apply 的一个很好的候选。您可以在计算列值的同一行中执行此操作,方法是在末尾放置 .apply(lambda x: x/np.timedelta64(1,'D')) 以在列级别应用转换。例如s3=(s1-s2).apply(lambda x: x/np.timedelta64(1,'D'))。
  • 这种方法astype('timedelta64[D]')(约96ms)比dt.days.(约24s)的4,000,000行效率高很多。
【解决方案2】:

假设你有一个 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)

【讨论】:

    【解决方案3】:

    使用dt.days 以整数形式获取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 - 这是目前执行此操作的最佳方法,因为自提出此问题以来,pandas 软件包已取得进展。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 2015-03-03
    • 2013-03-05
    • 2019-05-21
    • 1970-01-01
    相关资源
    最近更新 更多