Окно Прокрутки Numpy С Минимальными Периодами И Максимумом (Похоже На Прокатку Панд, Но Numpy)

#python #pandas #numpy

Вопрос:

Я ищу (не могу видеть, что это уже где-то описано) создать скользящее окно, используя numpy вместо pandas.rolling (в первую очередь для скорости). Однако скользящее окно также должно быть функцией минимального и максимального количества экземпляров в окне и возвращать значение NaN, когда окно не может быть создано. Это похоже на pandas.rolling с аргументами, установленными для размера окна (максимального) и min_periods. Например:

Установите Min_periods = 3 и Max_periods = 7, см. Ниже пример предполагаемого окна:

 index  values  intended_window
0      10      np.nan
1      11      np.nan
2      12      [10,11,12]
3      13      [10,11,12,13]
4      14      [10,11,12,13,14]
5      15      [10,11,12,13,14,15]
6      16      [10,11,12,13,14,15,16]
7      17      [11,12,13,14,15,16,17]
8      18      [12,12,14,15,16,17,18]
9      19      [13,14,15,16,17,18,19]
 

Я вижу примеры того, как может быть построено это раздвижное окно, когда для раздвижного окна не требуется ни максимума, ни минимума, например

 def rolling_window(a, window):
  shp = a.shape[:-1]   (a.shape[-1] - window   1, window)
  strides = a.strides   (a.strides[-1],)
  return np.lib.stride_tricks.as_strided(a, shape=shp, strides=strides)
 

Кто-нибудь знает, как я могу расширить это, чтобы вернуть окна, как в примере выше?

Комментарии:

1. Моя первая мысль, когда я вижу список/массивы, которые отличаются размером (0,3,7), звучит так: «Это невозможно сделать в numpy». Вы получаете быстрый numpy код (например, as_strided представление), имея дело с целыми массивами, с полными прямоугольными размерами. Неровные массивы медленные, немногим лучше, чем списки.

Ответ №1:

Пожалуйста, попробуйте следующее.

 def dataframe_striding(dataframe, window):
    '''
    Parameters
    ----------
    dataframe : Input Dataframe, in this case df with columns ['index', 'values'] present.
    window : Tuple denoting the window size.

    Returns
    -------
    dataframe : Pandas Dataframe

    '''
    lower_end, upper_end = window 
    if lower_end > upper_end:
        raise ValueError('Check window size!')

    results = []
    for i in range(dataframe.shape[0]):
        l = [k for k in dataframe['values'][:i 1]]        
        if len(l) < lower_end:                 # checks for minimum window length
            l = np.nan
            results.append(l)
        elif lower_end <= len(l) <= upper_end: # checks for required window length
            results.append(l)
        else:                                  # checks for maximum window length
            l = l[-upper_end:]
            results.append(l)
        
     dataframe['rolling_output'] = results     # appends output to input dataframe
     return dataframe 

# run above function #
final_df = dataframe_striding(df, window = (4,6))
 

Ответ №2:

 values = np.linspace(1, 10, num=10)
window_column = []
for i in range(len(values)):
    if i - 7 < 0:
        t = 0
    else:
        t = i - 7
    window = values[t:i]
    if len(window) < 3:
        window_column.append(np.nan)
    else:
        window_column.append(window)