Роллинг stdev для удаления выбросов с помощью NaNs - PullRequest
0 голосов
/ 15 октября 2019

Правильно, поэтому я немного подзабыл с питоном (вытащил его через 4 года) и искал решение этой проблемы. Хотя были похожие темы, я не смог понять, что я делаю не так.

У меня есть некоторые данные, которые выглядят следующим образом:

print (fwds)
        1y1yUSD   1y1yEUR    1y1yAUD  1y1yCAD   1y1yCHF   1y1yGBP  \
Date                                                                    
2019-10-15  1.47518 -0.503679   0.681473  1.84996 -0.804212  0.626394   
2019-10-14      NaN -0.513647   0.684232      NaN -0.815201  0.643280   
2019-10-11  1.51515 -0.520474   0.654544  1.84918 -0.812819  0.697584   
2019-10-10  1.39085 -0.538651   0.564055  1.72812 -0.846291  0.546696   
2019-10-09  1.30827 -0.568942   0.564897  1.63652 -0.896871  0.479307   
...             ...       ...        ...      ...       ...       ...   
1995-01-09  8.59473       NaN  10.830200  9.59729       NaN  9.407250   
1995-01-06  8.58316       NaN  10.851200  9.42043       NaN  9.434480   
1995-01-05  8.56470       NaN  10.839000  9.51209       NaN  9.560490   
1995-01-04  8.44306       NaN  10.745900  9.51142       NaN  9.507650   
1995-01-03  8.58847       NaN        NaN  9.38380       NaN  9.611590   

Проблема в том, что качество данных невелико, и мне нужно удалять выбросы по мере поступления (поскольку эти временные ряды былиТенденции и использование статического ZS не будет работать).

Я попробовал несколько решений. Одним из них было попытаться получить zscore, а затем отфильтровать большие. Однако, когда я пытаюсь вычислить zscore, мой результат - все NaN:

def zscore(x, window):
    r = x.rolling(window=window)
    m = r.mean().shift(1)
    s = r.std(ddof=0, skipna=True).shift(1)
    z = (x-m)/s
    return z
print (fwds)
print (zscore(fwds, 200))
        1y1yUSD  1y1yEUR  1y1yAUD  1y1yCAD  1y1yCHF  1y1yGBP  1y1yJPY  \
Date                                                                        
2019-10-15      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-10-14      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-10-11      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-10-10      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-10-09      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
...             ...      ...      ...      ...      ...      ...      ...   
1995-01-09      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
1995-01-06      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
1995-01-05      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
1995-01-04      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
1995-01-03      NaN      NaN      NaN      NaN      NaN      NaN      NaN 

Другой подход:

r = fwds.rolling(window=200)
large = r.mean() + 4 * r.std()
small = r.mean() - 4 * r.std()
print(fwds[fwds > mps])
print (fwds[fwds < mps])

возвращает:

   1y1yUSD  1y1yEUR  1y1yAUD  1y1yCAD  1y1yCHF  1y1yGBP  1y1yJPY  \
Date                                                                        
2019-10-15      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-10-14      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-10-11      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-10-10      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
2019-10-09      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
...             ...      ...      ...      ...      ...      ...      ...   
1995-01-09      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
1995-01-06      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
1995-01-05      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
1995-01-04      NaN      NaN      NaN      NaN      NaN      NaN      NaN   
1995-01-03      NaN      NaN      NaN      NaN      NaN      NaN      NaN 

для обоих макс. и мин. Кто-нибудь имеет какие-либо идеи, как бороться с этими проклятыми NaN при расчете скользящих stdev или zscores?

Любые намеки приветствуются. Спасибо!

Редактировать: Для большей ясности я надеялся систематически убирать с графика такие вещи, как всплеск зеленой и коричневой линий:

fwds.plot()

Ссылка ниже: https://i.stack.imgur.com/udu5O.png

1 Ответ

0 голосов
/ 15 октября 2019

Добро пожаловать в переполнение стека .... в зависимости от вашего варианта использования (и сколько существует сумасшедших экстремальных значений) интерполяция данных должна отвечать всем требованиям ....

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

Вы можете использовать pandas 'DataFrame.interpolate, чтобы заполнить ваши значения NaN интерполированными значениями.

Из документов

Заполнение NaN в серии с помощью линейной интерполяции.

>>> s = pd.Series([0, 1, np.nan, 3])
>>> s
0    0.0
1    1.0
2    NaN
3    3.0
dtype: float64
>>> s.interpolate()
0    0.0
1    1.0
2    2.0
3    3.0
dtype: float64

Редактировать Я только что понял, что вы ищете рыночные дислокации, поэтому вы можете не использовать линейную интерполяцию, так как это отключит эффект пропущенных данных

...