'Sliding Window Date Range for pandas

Pandas date_range function allows us to make Rolling Windows with a frequency.

pd.date_range(start='2019-06-01', end='2019-07-01', freq='3D')

# Output
DatetimeIndex(['2019-06-01', '2019-06-04', '2019-06-07', '2019-06-10',
               '2019-06-13', '2019-06-16', '2019-06-19', '2019-06-22',
               '2019-06-25', '2019-06-28', '2019-07-01'],
              dtype='datetime64[ns]', freq='3D')

But I would like to create a sliding window of 3 days, as such.

[('2019-06-01', '2019-06-03'), ('2019-06-02', '2019-06-04'), ('2019-06-03', '2019-06-05'), ...]

Can I do it with pandas? Or shall I just write a loop to get me the dates?



Solution 1:[1]

Loop solution:

#change range do default days
r = pd.date_range(start='2019-06-01', end='2019-07-01')

#create tuples in list comprehension
L = [(d.strftime('%Y-%m-%d'), (d + pd.Timedelta(2, 'd')).strftime('%Y-%m-%d')) for d in r]
print (L)
[('2019-06-01', '2019-06-03'), ('2019-06-02', '2019-06-04'), ('2019-06-03', '2019-06-05'), 
 ('2019-06-04', '2019-06-06'), ('2019-06-05', '2019-06-07'), ('2019-06-06', '2019-06-08'), 
 ('2019-06-07', '2019-06-09'), ('2019-06-08', '2019-06-10'), ('2019-06-09', '2019-06-11'), 
 ('2019-06-10', '2019-06-12'), ('2019-06-11', '2019-06-13'), ('2019-06-12', '2019-06-14'), 
 ('2019-06-13', '2019-06-15'), ('2019-06-14', '2019-06-16'), ('2019-06-15', '2019-06-17'), 
 ('2019-06-16', '2019-06-18'), ('2019-06-17', '2019-06-19'), ('2019-06-18', '2019-06-20'), 
 ('2019-06-19', '2019-06-21'), ('2019-06-20', '2019-06-22'), ('2019-06-21', '2019-06-23'), 
 ('2019-06-22', '2019-06-24'), ('2019-06-23', '2019-06-25'), ('2019-06-24', '2019-06-26'), 
 ('2019-06-25', '2019-06-27'), ('2019-06-26', '2019-06-28'), ('2019-06-27', '2019-06-29'), 
 ('2019-06-28', '2019-06-30'), ('2019-06-29', '2019-07-01'), ('2019-06-30', '2019-07-02'), 
 ('2019-07-01', '2019-07-03')]

Strides solution:

r = pd.date_range(start='2019-06-01', end='2019-07-01').strftime('%Y-%m-%d').values

def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
L1 = list(map(tuple, rolling_window(r, 3)[:, [0, -1]].tolist()))

Solution 2:[2]

Convert datetimeindex to series s and use list, zip on s and s.shift(-2)

s = pd.date_range(start='2019-06-01', end='2019-07-01', freq='D').to_series()
list(zip(s.dt.strftime('%Y-%m-%d'), s.shift(-2).dropna().dt.strftime('%Y-%m-%d')))

Out[678]:
[('2019-06-01', '2019-06-03'),
 ('2019-06-02', '2019-06-04'),
 ('2019-06-03', '2019-06-05'),
 ('2019-06-04', '2019-06-06'),
 ('2019-06-05', '2019-06-07'),
 ('2019-06-06', '2019-06-08'),
 ('2019-06-07', '2019-06-09'),
 ('2019-06-08', '2019-06-10'),
 ('2019-06-09', '2019-06-11'),
 ('2019-06-10', '2019-06-12'),
 ('2019-06-11', '2019-06-13'),
 ('2019-06-12', '2019-06-14'),
 ('2019-06-13', '2019-06-15'),
 ('2019-06-14', '2019-06-16'),
 ('2019-06-15', '2019-06-17'),
 ('2019-06-16', '2019-06-18'),
 ('2019-06-17', '2019-06-19'),
 ('2019-06-18', '2019-06-20'),
 ('2019-06-19', '2019-06-21'),
 ('2019-06-20', '2019-06-22'),
 ('2019-06-21', '2019-06-23'),
 ('2019-06-22', '2019-06-24'),
 ('2019-06-23', '2019-06-25'),
 ('2019-06-24', '2019-06-26'),
 ('2019-06-25', '2019-06-27'),
 ('2019-06-26', '2019-06-28'),
 ('2019-06-27', '2019-06-29'),
 ('2019-06-28', '2019-06-30'),
 ('2019-06-29', '2019-07-01')]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Andy L.