В R вы можете вычислить скользящее среднее с указанным окном, которое может смещаться на указанную величину каждый раз.
Однако, может быть, я просто нигде не нашел его, но не похоже, что вы можете сделать это в пандах или какой-то другой библиотеке Python?
Кто-нибудь знает способ обойти это. Я приведу вам пример того, что я имею в виду:
Здесь у нас есть полугодовые данные, и я вычисляю двухмесячное скользящее среднее, которое меняется каждый месяц.
Таким образом, в RI можно сделать что-то вроде: two_month__movavg=rollapply(mydata,4,mean,by = 2,na.pad = FALSE)
В Python нет эквивалента?
EDIT1:
SETTLEMENTDATE NSW DEMAND ... VIC DEMAND VIC RRP
0 2006/01/01 00:30:00 8013.27833 ... 5657.67500 20.03
1 2006/01/01 01:00:00 7726.89167 ... 5460.39500 18.66
2 2006/01/01 01:30:00 7372.85833 ... 5766.02500 20.38
3 2006/01/01 02:00:00 7071.83333 ... 5503.25167 18.59
4 2006/01/01 02:30:00 6865.44000 ... 5214.01500 17.53
Вы можете использовать прокрутку снова, просто нужно немного поработать с указанием индекса
Здесь by = 2
by = 2
df.loc[df.index[np.arange(len(df))%by==1],'New']=df.Price.rolling(window=4).mean()
df
Price New
0 63 NaN
1 92 NaN
2 92 NaN
3 5 63.00
4 90 NaN
5 3 47.50
6 81 NaN
7 98 68.00
8 100 NaN
9 58 84.25
10 38 NaN
11 15 52.75
12 75 NaN
13 19 36.75
df.loc[df.index[np.arange(len(df))%by==1],'New'
Теперь это немного излишне для одномерного массива данных, но вы можете упростить его и извлечь то, что вам нужно. Поскольку панды могут полагаться на NumPy, вы можете проверить, как их прокручивать/шагать функции, если они реализованы. Результаты для 20 последовательных номеров. 7-дневное окно, шаг за шагом/на 2
z = np.arange(20)
z #array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
s = stride(z, (7,), (2,))
np.mean(s, axis=1) # array([ 3., 5., 7., 9., 11., 13., 15.])
Вот код, который я использую без основной части документации. Он получен из многих реализаций пошаговой функции в numpy, которые можно найти на этом сайте. Есть варианты и воплощение, это просто другое.
def stride(a, win=(3, 3), stepby=(1, 1)):
"""Provide a 2D sliding/moving view of an array.
There is no edge correction for outputs. Use the 'pad_' function first."""
err = """Array shape, window and/or step size error.
Use win=(3,) with stepby=(1,) for 1D array
or win=(3,3) with stepby=(1,1) for 2D array
or win=(1,3,3) with stepby=(1,1,1) for 3D
---- a.ndim != len(win) != len(stepby) ----
"""
from numpy.lib.stride_tricks import as_strided
a_ndim = a.ndim
if isinstance(win, int):
win = (win,) * a_ndim
if isinstance(stepby, int):
stepby = (stepby,) * a_ndim
assert (a_ndim == len(win)) and (len(win) == len(stepby)), err
shp = np.array(a.shape) # array shape (r, c) or (d, r, c)
win_shp = np.array(win) # window (3, 3) or (1, 3, 3)
ss = np.array(stepby) # step by (1, 1) or (1, 1, 1)
newshape = tuple(((shp - win_shp) // ss) + 1) + tuple(win_shp)
newstrides = tuple(np.array(a.strides) * ss) + a.strides
a_s = as_strided(a, shape=newshape, strides=newstrides, subok=True).squeeze()
return a_s
Я не смог указать, что вы можете создать вывод, который вы можете добавить в качестве столбца в панд. Возвращаясь к исходным определениям, использованным выше
nans = np.full_like(z, np.nan, dtype='float') # z is the 20 number sequence
means = np.mean(s, axis=1) # results from the strided mean
# assign the means to the output array skipping the first and last 3 and striding by 2
nans[3:-3:2] = means
nans # array([nan, nan, nan, 3., nan, 5., nan, 7., nan, 9., nan, 11., nan, 13., nan, 15., nan, nan, nan, nan])