来自pd.date_range('2016-01', '2016-05', freq='M', ).strftime('%Y-%m')
,上个月是2016-04
,但我原以为2016-05
。在我看来,这个函数的行为类似于range
方法,其中end参数不包含在返回的数组中。
有没有办法让结束月份包含在返回的数组中,而不处理结束月份的字符串?
答案 0 :(得分:6)
对于后来的人群。您也可以尝试使用月 - 开始频率。
>>> pd.date_range('2016-01', '2016-05', freq='MS', format = "%Y-%m" )
DatetimeIndex(['2016-01-01', '2016-02-01', '2016-03-01', '2016-04-01',
'2016-05-01'],
dtype='datetime64[ns]', freq='MS')
答案 1 :(得分:5)
一种方法可以在不弄乱月份的情况下自行完成。
pd.date_range(*(pd.to_datetime(['2016-01', '2016-05']) + pd.offsets.MonthEnd()), freq='M')
DatetimeIndex(['2016-01-31', '2016-02-29', '2016-03-31', '2016-04-30',
'2016-05-31'],
dtype='datetime64[ns]', freq='M')
答案 2 :(得分:5)
初始化date_range
后,您可以使用.union
添加下一个逻辑值。它应该按照任何频率编写:
d = pd.date_range('2016-01', '2016-05', freq='M')
d = d.union([d[-1] + 1]).strftime('%Y-%m')
或者,您可以使用period_range
代替date_range
。根据您的意图,这可能不是正确的选择,但它满足您的问题:
pd.period_range('2016-01', '2016-05', freq='M').strftime('%Y-%m')
在任何一种情况下,结果输出都是预期的:
['2016-01' '2016-02' '2016-03' '2016-04' '2016-05']
答案 3 :(得分:1)
包括在date_range
来电
pd.date_range('2016-01-31', '2016-05-31', freq='M', ).strftime('%Y-%m')
array(['2016-01', '2016-02', '2016-03', '2016-04', '2016-05'],
dtype='|S7')
答案 4 :(得分:1)
在数据框中使用日期时间对象时,我遇到了类似的问题。我将通过.min()和.max()函数设置边界,然后使用pd.date_range函数填写缺少的日期。不幸的是,返回的列表/ df缺少最大值。
我为此找到了两种解决方法:
1)在pd.date_range函数中添加“ closed = None”参数。这在下面的示例中起作用;但是,当仅使用数据帧时,它对我不起作用(不知道为什么)。
2)如果选项#1不起作用,则可以使用datetime.timedelta()函数添加一个额外的单位(在本例中为一天)。在下面的情况下,它的索引超过一天,但是如果date_range函数不能为您提供完整范围,它可以为您工作。
import pandas as pd
import datetime as dt
#List of dates as strings
time_series = ['2020-01-01', '2020-01-03', '2020-01-5', '2020-01-6', '2020-01-7']
#Creates dataframe with time data that is converted to datetime object
raw_data_df = pd.DataFrame(pd.to_datetime(time_series), columns = ['Raw_Time_Series'])
#Creates an indexed_time list that includes missing dates and the full time range
#Option No. 1 is to use the closed = None parameter choice.
indexed_time = pd.date_range(start = raw_data_df.Raw_Time_Series.min(),end = raw_data_df.Raw_Time_Series.max(),freq='D',closed= None)
print('indexed_time option #! = ', indexed_time)
#Option No. 2 if the function allows you to extend the time by one unit (in this case day)
#by using the datetime.timedelta function to get what you need.
indexed_time = pd.date_range(start = raw_data_df.Raw_Time_Series.min(),end = raw_data_df.Raw_Time_Series.max()+dt.timedelta(days=1),freq='D')
print('indexed_time option #2 = ', indexed_time)
#In this case you over index by an extra day because the date_range function works properly
#However, if the "closed = none" parameters doesn't extend through the full range then this is a good work around
答案 5 :(得分:0)
我不这么认为。 您需要添加(n + 1)边界
pd.date_range('2016-01', '2016-06', freq='M' ).strftime('%Y-%m')
开始和结束日期严格包含在内。所以它不会 如果指定,则生成这些日期之外的任何日期。 http://pandas.pydata.org/pandas-docs/stable/timeseries.html
无论哪种方式,您都必须手动添加一些信息。我相信再增加一个月并不是很多工作。
答案 6 :(得分:0)
对此问题的解释是,函数pd.to_datetime()
默认将'%Y-%m'
日期字符串转换为月份的第一天日期时间或'%Y-%m-01'
:
>>> pd.to_datetime('2016-05')
Timestamp('2016-05-01 00:00:00')
>>> pd.date_range('2016-01', '2016-02')
DatetimeIndex(['2016-01-01', '2016-01-02', '2016-01-03', '2016-01-04',
'2016-01-05', '2016-01-06', '2016-01-07', '2016-01-08',
'2016-01-09', '2016-01-10', '2016-01-11', '2016-01-12',
'2016-01-13', '2016-01-14', '2016-01-15', '2016-01-16',
'2016-01-17', '2016-01-18', '2016-01-19', '2016-01-20',
'2016-01-21', '2016-01-22', '2016-01-23', '2016-01-24',
'2016-01-25', '2016-01-26', '2016-01-27', '2016-01-28',
'2016-01-29', '2016-01-30', '2016-01-31', '2016-02-01'],
dtype='datetime64[ns]', freq='D')
然后一切都随之而来。指定freq='M'
包括2016年1月1日至2016年5月1日之间的月末,这是您收到的列表,不包括2016年5月31日。但是,如第二个答案所提供的那样,指定月份开始'MS'
包括2016-05-01,因为它在范围内。 pd.date_range()
的默认行为与range
方法不同,因为其中包括结尾。来自the docs:
closed 控制是否包括边界上的开始和结束。默认值包括两端的边界点。