Применение фильтра Савицкого-Голея к фрейму данных pandas

#python #pandas

#python #pandas

Вопрос:

У меня есть следующий набор данных временных рядов:

 import pandas as pd
from datetime import datetime
import numpy as np
from scipy.signal import savgol_filter

date_rng = pd.date_range(start='2020-07-01', end='2020-07-20', freq='d')
df = pd.DataFrame(date_rng, columns=['date'])
df['data'] = np.random.randint(0,100,size=(len(date_rng)))
  

Я хотел бы вычислить фильтр Савицкого-Голея и фрейм данных pandas, который я определил в следующей функции:

 def savgol(x, wl=3, p=2):
    return savgol_filter(x, window_length=wl, polyorder=p)

df['sav_gol'] = df['data'].apply(savgol)
  

При выполнении скрипта я получаю следующее сообщение об ошибке:

Ошибка значения: если режим «interp», window_length должен быть меньше или равен размеру x.

Редактировать:

Вот мой скорректированный набор данных с группами. Я бы применил функцию savgol к этому набору данных:

 df = pd.DataFrame({
    'date':date_rng,
    'value':np.random.randint(0,100,size=(len(date_rng))),
    'group':'a'
})
df2 = pd.DataFrame({
    'date':date_rng,
    'value':np.random.randint(0,100,size=(len(date_rng))),
    'group':'b'
})

df = df.append(df2, ignore_index=True)
  

Это была бы моя попытка:

 df['sav_gol'] = df.groupby('group')['value'].apply(savgol)
  

Любая помощь будет высоко оценена!

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

1. Трудно сказать без образцов данных. Можно предположить, что в вашем наборе данных меньше 21 строки, что меньше вашего размера окна.

2. вы применяете фильтр по строкам, он получает одно значение для каждого вызова, но для работы ему нужны как минимум wl элементы, вероятно, вам следует вызывать savgol_filter весь столбец без использования apply . Кроме того, ваш образец набора данных содержит 20 строк, поэтому он все равно не будет работать с окном длиной 21

3. Я уменьшил размер окна до 3, и все равно получаю ту же ошибку

4. смотрите мой комментарий, этого недостаточно, потому что вы используете «применить» по строкам

5. df['sav_gol'] = savgol(df["data"])

Ответ №1:

Это действительно сработало:

 df['savgol'] = df.groupby('group')['value'].transform(lambda x: savgol_filter(x, 5,2))