Всё о методе shift() в pandas
Предположим, вы столкнулись с ситуацией, когда вам нужно сдвинуть все строки в датафрейме или вы хотите вычислить разницу в последовательных рядах. Метод Pandas shift()
вам в помощь.
Затронем пару теоретических и пару практических моментов:
Сдвиг значений с помощью periods
Метод shift()
сдвигает индексы в датафрейме на нужное количество значений. Простейший вызов этой функции должен содержать аргумент periods
(по умолчанию periods=1
), который представляет собой количество шагов сдвига для нужной оси. По умолчанию сдвигаются значения по вертикали вдоль оси 0
. Отсутствующие значения, появившихся в результате сдвига, будут автоматически заполнены NaN
.
Давайте посмотрим, как это работает, на примере. Создадим датафрейм:
df = pd.DataFrame({ "A": [1, 2, 3, 4, 5], "B": [10, 20, 30, 40, 50] })
Сдвинем индекс на 1 строку по вертикали:
df.shift(periods=1) # Так тоже можно: df.shift(1)
Для замены NaN
можно использовать аргумент fill_value
и проставить вместо пропусков 0
:
df.shift(periods=1, fill_value=0)
Кроме того, в periods
можно передавать отрицательные числа, чтобы сдвигать значения в противоположном направлении.
Чтобы сдвинуть значения по горизонтали, можно задать axis=1
:
df.shift(periods=1, axis=1)
Сдвиг данных временного ряда с помощью freq
У метода shift()
также есть аргумент freq
. он позволяет выполнять сдвиг на основе некоей заданной частоты, что полезно при работе с данными временных рядов.
Чтобы использовать аргумент freq
, необходимо убедиться, что индексами в вашем датафрейме являются типы date
или datetime
, иначе возникнет ошибка NotImplementedError
.
Давайте посмотрим, как это работает, на примере:
df = pd.DataFrame({ "A": [1, 2, 3, 4, 5], "B": [10, 20, 30, 40, 50] }, index=pd.date_range("2020-01-01", freq="D", periods=5) )
df.shift(freq='10D') # эквивиалент: df.shift(periods=10, freq="D")
При выполнении той же операции с помощью только одного аргумента periods
вы получите следующий результат. Конечно, это не то, чего мы хотим.
Вычисление разницы в последовательных рядах
Предположим, вам нужно использовать значение предыдущего ряда для расчёта чего-либо. Тут тоже пригодится метод shift()
:
df = pd.DataFrame({ "date": pd.date_range("2020-01-01", freq="D", periods=5), "sales": [22, 30, 32, 25, 42] })
Рассчитаем изменение продаж в последовательных рядах.
df["diff"] = df["sales"] - df.shift(1)["sales"]
Короче, эта функция крайне полезна при работе с временными рядами. Давайте рассмотрим еще один практический пример.
Вычисление разницы для временного ряда
Теперь предположим, что вас попросили рассчитать изменение продаж за 7 дней следующим образом:
value_1 = Day_8 - Day_1 value_2 = Day_9 - Day_2 value_3 = Day_10 - Day_3 ... value_n = Day_N - Day_N-7
Использование метода shift()
с аргументом freq
— идеальный способ решения этой задачи. Давайте воспользуемся методом read_csv()
(пример данных здесь) с аргументами parse_dates
и index_col
для формирования датафрейма.
df = pd.read_csv( "https://raw.githubusercontent.com/obulygin/content/main/pandas_shift/time_series.csv", parse_dates=["date"], index_col=["date"], )
Обратите внимание, что запись для "2020-01-08" отсутствует. Выполнив df.shift(freq='7D')
, вы должны получить результат с записью для "2020-01-08"
.
Затем мы можем рассчитать изменение продаж за 7 дней:
the_7_days_diff = df["sales"] - df.shift(freq="7D")["sales"]
- в результате есть запись для "2020-01-08";
- значение "2020-01-08" —
NaN
, потому что изначально в данных не было такого значения; - значения для даты с "2020-01-01" по "2020-01-07" —
NaN
, потому что их нет и вdf.shift(freq='7D')
; - последние 6 записей —
NaN
, потому что в датафрейме не было этих значений.
Заключение
Метод shift()
может быть очень полезен, когда нужно сдвинуть все строки в датафрейме или требуется использовать предыдущую строку для вычислений. А ещё он применяется при работе с данными временных рядов.
Рекомендуем также ознакомиться с документацией метода.
Источник: Medium
Перевод и адаптация: Екатерина Прохорова