pandas time_range不从起始日期启动

5 投票
3 回答
638 浏览
提问于 2025-04-18 02:58

我最近开始使用pandas这个工具,但在使用date_range的时候遇到了一些问题。

In [168]: pd.date_range("2013-07-01", "2013-10-03", freq='W').to_series()
Out[168]: 
2013-07-07   2013-07-07
2013-07-14   2013-07-14
2013-07-21   2013-07-21
2013-07-28   2013-07-28
2013-08-04   2013-08-04
2013-08-11   2013-08-11
2013-08-18   2013-08-18
2013-08-25   2013-08-25
2013-09-01   2013-09-01
2013-09-08   2013-09-08
2013-09-15   2013-09-15
2013-09-22   2013-09-22
2013-09-29   2013-09-29
Freq: W-SUN, dtype: datetime64[ns]

在上面的例子中,我原本期待第一个索引是2013-07-01,而不是2013-07-07。我检查了一下,发现默认情况下,date_range会把左右两边都算上。然后我还试了其他一些频率,比如W-MON,但也没有解决问题。

3 个回答

0
df['Date'] = pd.date_range(start='2023-09-13', freq = 'W', periods=3)
Date
0 2023-09-17
1 2023-09-24
2 2023-10-01

问题还是存在。

0

这个 pandas 文档中提到,

使用上面提到的时间偏移别名时,需要注意的是,像 date_range() 和 bdate_range() 这样的函数只会返回在 start_date 和 end_date 定义的时间范围内的时间戳。如果 start_date 不符合设定的频率,返回的时间戳会从下一个有效的时间戳开始;同样的,end_date 也是,返回的时间戳会在上一个有效的时间戳停止。

如果你往下滚动一点,你会看到可以使用锚定偏移

你可以使用time模块来确定指定日期是星期几,然后把它作为偏移量。

这里有一个简单的例子:

import pandas as pd
import time

start_time = time.strptime("2013-07-01", "%Y-%m-%d")

print(pd.date_range("2013-07-01", "2013-10-03", freq=f'W-{time.strftime("%a", start_time)}').to_series())

输出结果是:

2013-07-01   2013-07-01
2013-07-08   2013-07-08
2013-07-15   2013-07-15
2013-07-22   2013-07-22
2013-07-29   2013-07-29
2013-08-05   2013-08-05
2013-08-12   2013-08-12
2013-08-19   2013-08-19
2013-08-26   2013-08-26
2013-09-02   2013-09-02
2013-09-09   2013-09-09
2013-09-16   2013-09-16
2013-09-23   2013-09-23
2013-09-30   2013-09-30
Freq: W-MON, dtype: datetime64[ns]
1

8年后,1.5.2版本还是有同样的bug:

my_period = pd.date_range('2015-09-01', '2016-07-01', freq='3M')
my_period

结果是

DatetimeIndex(['2015-09-30', '2015-12-31', '2016-03-31', '2016-06-30'], dtype='datetime64[ns]', freq='3M')

我认为默认情况下,开始时间应该固定在给定的日期上,也就是2015年9月1日的00:00。这里的星期天功能不太管用。

有趣的是,如果我加一个小时,它会正确使用这个小时,但日期还是不对:

my_period = pd.date_range('2015-09-01 02:10', '2016-07-01', freq='3M')
my_period

DatetimeIndex(['2015-09-30 02:10:00', '2015-12-31 02:10:00',
               '2016-03-31 02:10:00', '2016-06-30 02:10:00'],
              dtype='datetime64[ns]', freq='3M')

撰写回答