pandas 的日期范围

Date ranges with pandas

我正在尝试创建一个脚本,在输入开始日期和结束日期后生成日期范围。

例如:

start = 2016-01-01

end = 2017-10-01

脚本将输出如下列表:

['2016-01-01 2016-04-01',

2016-04-01 2016-07-01',

‘2016-07-01 2016-10-01',

‘2016-10-01 2017-01-01',

'2017-01-01 2017-04-01',

‘2017-04-01 2017-07-01',

‘2017-07-01 2017-10-01']

到目前为止,我已经设法生成了所有必要的时间范围,但我无法将每个单独的日期分组为这些时间范围所需的时间格式。

到目前为止,这是我的代码

start = '2016-01-01'
end = str(pd.to_datetime('today').replace(day=1))[:10]
dates = list(pd.date_range(start, end, freq="3MS"))
new_dates = []
for i in dates:
    i= str(i)[:10]
    new_dates.append(i)

输出如下: `

['2016-01-01',
 '2016-04-01',
 '2016-07-01',
 '2016-10-01',
 '2017-01-01',
 '2017-04-01',
 '2017-07-01',
 '2017-10-01']

如果有人帮助我完成脚本的最后一部分,我将不胜感激。

使用dates数组,使用dates[:-1]删除最后一个元素,使用dates[1:]删除第一个元素,然后column_stack两个数组:

import numpy as np

start = '2016-01-01'
end = pd.to_datetime('today').replace(day=1)
dates = pd.date_range(start, end, freq="3MS").strftime('%Y-%m-%d')

np.column_stack((dates[:-1], dates[1:]))
#array([['2016-01-01', '2016-04-01'],
#       ['2016-04-01', '2016-07-01'],
#       ['2016-07-01', '2016-10-01'],
#       ['2016-10-01', '2017-01-01'],
#       ['2017-01-01', '2017-04-01'],
#       ['2017-04-01', '2017-07-01'],
#       ['2017-07-01', '2017-10-01']], 
#      dtype='<U10')

要获得每个范围的条目,我们可以将它们相加:

np.char.add(np.char.add(dates[:-1], ' '), dates[1:])
#array(['2016-01-01 2016-04-01', '2016-04-01 2016-07-01',
#       '2016-07-01 2016-10-01', '2016-10-01 2017-01-01',
#       '2017-01-01 2017-04-01', '2017-04-01 2017-07-01',
#       '2017-07-01 2017-10-01'], 
#      dtype='<U21')

添加一个 numpy 的免费替代品

import pandas as pd

start = '2016-01-01'
end = pd.to_datetime('today').replace(day=1)
dates = pd.date_range(start, end, freq="3MS").strftime('%Y-%m-%d')

coupled_dates = []

for date in zip(*(dates[:-1], dates[1:])):
    coupled_dates.append(' '.join(date))

coupled_dates

这里需要注意的是,它的执行速度大约是@Psidom 提供的第一个 numpy 解决方案的两倍。使用 "propper" 第二个版本时,numpy 的性能比 python 差 3 倍。

优点是,如果您无权访问 pandas/numpy.[=16=,您很可能将此解决方案与标准 datetime 模块一起使用]

在分别删除第一个和最后一个元素后,您可以先将两个单独的列表合并到一个元组列表中(根据@Psidom 的回答):

dates1 = dates[:-1]
dates2 = dates[1:]

这将生成两个列表,其中 dates1 缺少原始列表的最后一个元素,dates2 缺少原始列表的第一个元素。

dates3 = zip(dates1, dates2)

这将在 dates3 中生成如下结构:

[('2016-01-01', '2016-04-01'), ('2016-04-01', '2016-07-01'), ...]

现在您可以像这样生成所需输出字符串的列表:

output = [x + ' ' + y for x,y in dates3]

您也可以将所有这些写在一行中,但这可能会影响可读性:

output = [x + ' ' + y for x,y in zip(dates[:-1], dates[1:])] 
import pandas as pd
a = pd.date_range("20160101","20171001", freq="3MS") # given date range
b =a.map(str).map(lambda x: x[:10]) # to_string and take 10 characters 
c = b[:-1]+" "+b[1:] # shift the index array and join strings
d = c.tolist() # cast to python's list if you need