Использование объекта pandas Rolling для создания скользящего окна списков

Этот выдающийся пост довольно ясно показывает, как использовать pandas cumsum() DataFrame для построения трехмерного тензора, содержащего столбец со списками списков, размеры которых делают их пригодными для использования в качестве входных данных временных рядов в LSTM. Я хотел бы сделать что-то очень похожее, но с скользящим списком списков вместо совокупного агрегирования списков.

Например. Скажем, у вас был DataFrame с 3 временными рядами, таким образом:

 A   B   C
 1   2   3
 4   5   6
 7   8   9
10  11  12

В статье, на которую я ссылался выше, показано, как использовать pandas cumsum() для создания столбца DataFrame из вложенных списков, которые выглядят следующим образом:

[[1, 2, 3]]
[[1, 2, 3], [4, 5, 6]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Ключевые строки кода Python, позволяющие добиться этого, следующие:

input_cols =  list(df.columns)
df['single_list'] = df[input_cols].apply(
                       tuple, axis=1).apply(list)
df['double_encapsulated'] = df.single_list.apply(
                                      lambda x: [list(x)])

Но мне нужно скользящее окно списков, а не совокупную сумму списков. Должно получиться так:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[4, 5, 6], [7, 8, 9], [10, 11, 12]]
[[7, 8, 9], [10, 11, 12], [13, 14, 15]]

Можно ли это сделать с помощью объекта Rolling?


person John Strong    schedule 30.01.2019    source источник


Ответы (2)


Вот несколько приемов для достижения желаемых результатов:

import pandas as pd
dd = {'A': {0: 1, 1: 4, 2: 7, 3: 10, 4: 13},
 'B': {0: 2, 1: 5, 2: 8, 3: 11, 4: 14},
 'C': {0: 3, 1: 6, 2: 9, 3: 12, 4: 15}}
df = pd.DataFrame(dd)

list_of_indexes=[]
df.index.to_series().rolling(3).apply((lambda x: list_of_indexes.append(x.tolist()) or 0), raw=False)
list_of_indexes

d1 = df.apply(tuple,axis=1).apply(list)
[[d1[ix] for ix in x] for x in list_of_indexes]

Выход:

[[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
 [[4, 5, 6], [7, 8, 9], [10, 11, 12]],
 [[7, 8, 9], [10, 11, 12], [13, 14, 15]]]

Подробности:

Создайте пустой список. Используйте прокрутку и примените с уловкой функции, которая возвращает None и оператор «или» с нулем, чтобы разрешить прокрутку apply для возврата 0 (числа). Однако на самом деле нам нужны результаты функции "append" в данном случае. Мы используем индекс фрейма данных в качестве входных данных для нашей скользящей функции, поэтому «list_of_indexes» - это скользящий список индексов исходного фрейма данных, df. Теперь давайте изменим фрейм данных, чтобы преобразовать строки в список, который равен d1, используя «применить кортеж» и «применить список».

Наконец, давайте воспользуемся d1, чтобы заменить наш list_of_indexes соответствующим списком из исходного фрейма данных, используя понимание списка.

person Scott Boston    schedule 30.01.2019
comment
Какую версию Python вы используете? Я получаю следующее: TypeError: apply () получил неожиданный аргумент ключевого слова "raw". - person John Strong; 30.01.2019
comment
Я использую панды 0.24.0. - person Scott Boston; 30.01.2019

Поскольку pandas 1.1 катящиеся объекты являются повторяемыми, и вы можете:

[win.values.tolist() for win in df.rolling(3, axis=1) if win.shape[0] == 3]

С if мы гарантируем, что получаем только полные окна.

person Philipp    schedule 09.12.2020