Скользящий минимум массива, чтобы первые значения были минимумом окна, а не NaN - PullRequest
1 голос
/ 22 апреля 2020

До сих пор я пандировал 'мой массив', чтобы я мог использовать функции Panda + min (), я использую окно с шириной 3.

import pandas as pd
import numpy as np

q = np.array([ 4.71858472,  4.5252853 ,  3.43745458,  1.978533  , -0.50446801,
   -0.25213346,  0.04942399, -0.76639228,  0.17852748,  0.58374693])

df_q = pd.DataFrame(q,columns=['min_q'])

df_min = df_q.rolling(3,min_periods=1).min()

Что Я получаю, что Pandas вставляет значения NaN для первых 2 возвращаемых значений (имеет смысл), если min_periods не указано, или когда указано, он принимает только указанные значения (тоже имеет смысл). Я хотел бы знать, возможно ли получить возвращенный ряд, в котором начальные значения возвращенного набора равны наименьшему из первого окна, а не значениям минимальных периодов.

Что я Получение:

array([[ 4.71858472], [ 4.5252853 ],[ 3.43745458],[ 1.978533  ],[-0.50446801],[-0.50446801],[-0.50446801],[-0.76639228],[-0.76639228],[-0.76639228]])

Что я хочу:

array([[ 3.43745458], [ 3.43745458 ],[ 1.978533],[ 0.50446801 ],[-0.50446801],[-0.50446801],[-0.76639228],[-0.76639228],[-0.76639228],[0.17852748]])

Это вообще возможно сделать в Pandas?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Если вы ищете производительность, вы можете использовать scipy.ndimage.filters.minimum_filter1d :

import numpy as np
import pandas as pd
from scipy.ndimage.filters import minimum_filter1d

q = np.array([ 4.71858472,  4.5252853 ,  3.43745458,  1.978533  , -0.50446801,
   -0.25213346,  0.04942399, -0.76639228,  0.17852748,  0.58374693])

def rolling_scipy(a, W):
    hW = (W-1)//2 
    out = minimum_filter1d(a, size=W, origin=hW)
    out[:W-1] = out[W-1]
    return out

%timeit rolling_scipy(q, 3)
12.8 µs ± 1.32 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

def rolling_pandas(a, W):
    df = pd.DataFrame(a, columns=['min_q'])
    return df.rolling(W).min().bfill()

%timeit rolling_pandas(q, W)
1.41 ms ± 146 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1 голос
/ 22 апреля 2020

Я думаю, вам нужно DataFrame.bfill

>>> df_min = df_q.rolling(3).min().bfill()
>>> df_min
      min_q
0  3.437455
1  3.437455
2  3.437455
3  1.978533
4 -0.504468
5 -0.504468
6 -0.504468
7 -0.766392
8 -0.766392
9 -0.766392
...