Pandas date_range生成每月初的月度数据

114

我正在尝试生成一个每月数据的日期范围,在这个范围内,日期总是在每个月的开头:

pd.date_range(start='1/1/1980', end='11/1/1991', freq='M')

这会生成 1/31/19802/29/1980等等。相反,我只想要 1/1/19802/1/1980等。

我看到其他问题问如何生成始终在某个月的特定日期的数据,有些答案说这是不可能的,但每个月初肯定是可以的!

2个回答

210

您可以通过将freq参数从'M'更改为'MS'来实现此操作:

d = pandas.date_range(start='1/1/1980', end='11/1/1990', freq='MS')    
print(d)

现在应该输出:

DatetimeIndex(['1980-01-01', '1980-02-01', '1980-03-01', '1980-04-01',
               '1980-05-01', '1980-06-01', '1980-07-01', '1980-08-01',
               '1980-09-01', '1980-10-01', 
               ...
               '1990-02-01', '1990-03-01', '1990-04-01', '1990-05-01',
               '1990-06-01', '1990-07-01', '1990-08-01', '1990-09-01',
               '1990-10-01', '1990-11-01'],
              dtype='datetime64[ns]', length=131, freq='MS', tz=None)

请查看文档中的偏移别名部分,其中指出'M'代表月底频率(月末频率),而'MS'代表月初频率(月首频率)。


13
值得注意的是pandas.date_range()只包括在定义的时间间隔内部的日期,这可能不符合预期:
start = "2020-03-08"
end = "2021-03-08"
pd.date_range(start, end, freq='MS')

导致

DatetimeIndex(['2020-04-01', '2020-05-01', '2020-06-01', '2020-07-01',
           '2020-08-01', '2020-09-01', '2020-10-01', '2020-11-01',
           '2020-12-01', '2021-01-01', '2021-02-01', '2021-03-01'],
          dtype='datetime64[ns]', freq='MS')

对于MS,解决包含开放月份第一天的方法是仅使用开始日期的年份和月份:

pd.date_range(start[:7], end, freq='MS')

然后会给予

DatetimeIndex(['2020-03-01', '2020-04-01', '2020-05-01', '2020-06-01',
           '2020-07-01', '2020-08-01', '2020-09-01', '2020-10-01',
           '2020-11-01', '2020-12-01', '2021-01-01', '2021-02-01',
           '2021-03-01'],
          dtype='datetime64[ns]', freq='MS')

如果您希望每个月都保持相同的起始日期,那么您可以使用pd.DateOffset()添加偏移量:

pd.date_range(start[:7], end, freq='MS') + pd.DateOffset(days=7)

将会给予

DatetimeIndex(['2020-03-08', '2020-04-08', '2020-05-08', '2020-06-08',
           '2020-07-08', '2020-08-08', '2020-09-08', '2020-10-08',
           '2020-11-08', '2020-12-08', '2021-01-08', '2021-02-08',
           '2021-03-08'],
          dtype='datetime64[ns]', freq=None)

如评论中所述,请注意,对于偏移量大于或等于28的情况,此解决方法可能会带来麻烦。


1
如果所需日期是2月29日,而2月只有28天,则会出现问题。 - anishtain4
@anishtain4 对的(对于最后一部分,添加一个偏移量)。实际上,使用这种方法的问题出现在任何偏移量等于或高于28的情况下。 - Skippy le Grand Gourou
“MS” 对于 date_range意味着“使范围从下个月的开始算起”。但它只包括在 startend 定义的范围内的日期点。如果 start 是所提供频率中的日期点,则 date_range 在结果中返回该日期点。 - pablete
1
@pablete 这确实措辞不当。已更新回答,感谢您的评论。 - Skippy le Grand Gourou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接