如何使用 pandas.date_range() 在指定的开始日期和结束日期之间获取具有 n 个指定周期(相等)的时间序列

Posted

技术标签:

【中文标题】如何使用 pandas.date_range() 在指定的开始日期和结束日期之间获取具有 n 个指定周期(相等)的时间序列【英文标题】:How can I use pandas.date_range() to obtain a time series with n specified periods (equal) between a specified start and end date 【发布时间】:2014-11-05 21:49:21 【问题描述】:

我想获取一个或一系列介于开始日期和结束日期之间的 n 个日期(包括这些界限),但是

dateIndex=pd.date_range(start=dt.datetime.today().date(), end=pd.to_datetime(expiry).date(), periods=n)

带有 ValueError 的结果:必须指定开始、结束或句点中的两个。我不能使用 freq=Freq 参数,因为我的日期范围不会是统一的 - 它可能是一个月到 2 年的跨度,因此我想要一个具有 n 个点的等距时间序列。

谢谢!

【问题讨论】:

【参考方案1】:

从 Pandas 0.23(或更早版本)开始,您可以像最初尝试的那样使用 pandas.date_range。它不会引发错误并且会按照您的预期运行。示例:

pd.date_range('2016-01-01', '2017-01-01', periods=13, tz='utc')
Out[44]: 
DatetimeIndex(['2016-01-01 00:00:00+00:00', '2016-01-31 12:00:00+00:00',
               '2016-03-02 00:00:00+00:00', '2016-04-01 12:00:00+00:00',
               '2016-05-02 00:00:00+00:00', '2016-06-01 12:00:00+00:00',
               '2016-07-02 00:00:00+00:00', '2016-08-01 12:00:00+00:00',
               '2016-09-01 00:00:00+00:00', '2016-10-01 12:00:00+00:00',
               '2016-11-01 00:00:00+00:00', '2016-12-01 12:00:00+00:00',
               '2017-01-01 00:00:00+00:00'],
              dtype='datetime64[ns, UTC]', freq=None)

2016 年(闰年)有 366 天,因此时间戳相隔 30.5 天。

【讨论】:

【参考方案2】:

我认为你不能只用date_range 做到这一点,但为什么不使用numpy 的linspace

In [11]: start = pd.Timestamp('2012-01-01')

In [12]: end = pd.Timestamp('2012-02-01')

In [13]: np.linspace(start.value, end.value, 10)  # 10 dates inclusive
Out[13]:
array([  1.32537600e+18,   1.32567360e+18,   1.32597120e+18,
         1.32626880e+18,   1.32656640e+18,   1.32686400e+18,
         1.32716160e+18,   1.32745920e+18,   1.32775680e+18,
         1.32805440e+18])

In [14]: pd.to_datetime(np.linspace(start.value, end.value, 10))
Out[14]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2012-01-01 00:00:00, ..., 2012-02-01 00:00:00]
Length: 10, Freq: None, Timezone: None

可以将此作为频率传递,但对于不均分的时间,这可能/将会不准确:

In [21]: (end - start)/ 9
Out[21]: datetime.timedelta(3, 38400)

In [22]: ((end - start)/ 9).total_seconds()
Out[22]: 297600.0

# Note: perhaps there's a better way to pass this as a freq?
In [23]: pd.date_range(start=start, end=end, freq='%iS' % ((end - start)/ 9).total_seconds())
Out[23]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2012-01-01 00:00:00, ..., 2012-02-01 00:00:00]
Length: 10, Freq: 297600S, Timezone: None

【讨论】:

谢谢 - np.linspace 非常有用 - 我实际上将它与列表理解一起使用,在结束/开始时减去/添加天数。 @arosner09 如果有帮助请点赞/接受:meta.stackexchange.com/a/5235/184179 这很好用,但它似乎有点解决方法。如果指定了所有三个参数,为什么这不是pd.date_range 的默认行为?

以上是关于如何使用 pandas.date_range() 在指定的开始日期和结束日期之间获取具有 n 个指定周期(相等)的时间序列的主要内容,如果未能解决你的问题,请参考以下文章

具有特定时间范围的 Pandas date_range

date_range

pandas 之时间排序

时间序列--日期的范围频率及移动

如何以年份为频率创建熊猫 DatetimeIndex?

pandas 补充知识:data_range函数