pandas time_range不从起始日期启动
我最近开始使用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')