【问题标题】:Getting date ranges for multiple datetime pairs获取多个日期时间对的日期范围
【发布时间】:2018-04-08 16:19:45
【问题描述】:

给定一个形状为(n, 2)的日期时间数组:

x = np.array([['2017-10-02T00:00:00.000000000', '2017-10-12T00:00:00.000000000']], dtype='datetime64[ns]') 

x 的形状为(1, 2),但实际上它可能是(n, 2)n >= 1。在每一对中,第一个日期总是小于(或等于)第二个日期。我想获取x 中每对日期之间所有日期范围的列表。这就是我基本上正在做的事情:

np.concatenate([pd.date_range(*y, closed='right') for y in x])

它有效,给予

array(['2017-10-03T00:00:00.000000000', '2017-10-04T00:00:00.000000000',
       '2017-10-05T00:00:00.000000000', '2017-10-06T00:00:00.000000000',
       '2017-10-07T00:00:00.000000000', '2017-10-08T00:00:00.000000000',
       '2017-10-09T00:00:00.000000000', '2017-10-10T00:00:00.000000000',
       '2017-10-11T00:00:00.000000000', '2017-10-12T00:00:00.000000000'], dtype='datetime64[ns]')

但这很慢,因为列表比较 - 它没有像我想要的那样完全矢量化。我想知道是否有更好的方法来获取多对日期的日期范围?

我会根据需要提供尽可能多的说明。谢谢。

【问题讨论】:

  • Np.arange 适用于 datetime64 值
  • @hpaulj 太棒了np.concatenate([np.arange(row[0], row[1] + 1) for row in x.astype('datetime64[D]')]).astype('datetime64[ns]')

标签: python performance pandas numpy datetime


【解决方案1】:

这有点令人费解......
但是

d = np.array(1, dtype='timedelta64[D]')
x = x.astype('datetime64[D]')
deltas = np.diff(x, axis=1) / d
np.concatenate([
    i + np.arange(j + 1) for i, j in zip(x[:, 0], deltas[:, 0].astype(int))
]).astype('datetime64[ns]')

array(['2017-10-02T00:00:00.000000000', '2017-10-03T00:00:00.000000000',
       '2017-10-04T00:00:00.000000000', '2017-10-05T00:00:00.000000000',
       '2017-10-06T00:00:00.000000000', '2017-10-07T00:00:00.000000000',
       '2017-10-08T00:00:00.000000000', '2017-10-09T00:00:00.000000000',
       '2017-10-10T00:00:00.000000000', '2017-10-11T00:00:00.000000000',
       '2017-10-12T00:00:00.000000000'], dtype='datetime64[ns]')

工作原理

  • d代表一天
  • x 变成没有时间戳的日期
  • diff 让我知道天数差异......但在 timedelta 空间中
  • 我除以我的d,它也在timedelta空间中,尺寸消失了...留下float,我将其转换为int
  • 当我将x[:, 0] 对的第一列添加到整数数组中时,我会收到一个广播,即添加一个单位的x,即datetime64[D]。所以我要加一天。

源自/受@hpaulj启发
如果他们发布答案将删除

d = np.array(1, dtype='timedelta64[D]')
np.concatenate([np.arange(row[0], row[1] + 1, d) for row in x])

array(['2017-10-02T00:00:00.000000000', '2017-10-03T00:00:00.000000000',
       '2017-10-04T00:00:00.000000000', '2017-10-05T00:00:00.000000000',
       '2017-10-06T00:00:00.000000000', '2017-10-07T00:00:00.000000000',
       '2017-10-08T00:00:00.000000000', '2017-10-09T00:00:00.000000000',
       '2017-10-10T00:00:00.000000000', '2017-10-11T00:00:00.000000000',
       '2017-10-12T00:00:00.000000000'], dtype='datetime64[ns]')

【讨论】:

  • 哇,单双就快了 3 倍!它是如何工作的?
  • 多亏了你,我现在有点理解这些解决方案的工作原理了。我尝试与它们一起玩并为我的own use case 调整它们(只是一点点,不多)。感谢您的帮助。
  • 虽然我敢打赌你可以找到一个更好的解决方案来解决这个问题...... ;-)
  • 现在看(-:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多