Pandas заменить на NaN, если разница с предыдущей строкой превышает пороговое значение - PullRequest
3 голосов
/ 03 августа 2020

У меня есть полчаса df фрейма данных, из которого я хочу удалить выбросы.

date  = ['2015-02-03 23:00:00','2015-02-03 23:30:00','2015-02-04 00:00:00','2015-02-04 00:30:00']
value_column = [33.24  , 500  , 34.39  , 34.49 ]

df = pd.DataFrame({'value column':value_column})
df.index = pd.to_datetime(df['index'],format='%Y-%m-%d %H:%M')
df.drop(['index'],axis=1,inplace=True)

print(df.head())
                   value column  
index                                     
2015-02-03 23:00:00  33.24   
2015-02-03 23:30:00  500   
2015-02-04 00:00:00  34.39   
2015-02-04 00:30:00  34.49   

Я хочу удалить выбросы на основе разницы значений от одного часа к другому. Я хотел бы заменить значения выбросов на NaN, если абсолютная разница от одного часа к другому превышает заданный порог. Как я могу это сделать эффективно?

Я знаю, что могу получить разницу фрейма данных со строкой ниже, однако я не знаю, как заменить значения на nan в определенных индексах, где разница выше заданный порог. Есть идеи, как это сделать эффективно? (Предположим, например, что порог равен 100)

df = df.diff()

Я пробовал следующее, он не вызывает ошибок, но не работает:

df["value column"]=df["value column"].mask(df["value column"].diff().abs() > 100, np.nan) 

Ожидаемые результаты:

                   value column  
index                                     
2015-02-03 23:00:00  33.24   
2015-02-03 23:30:00  NaN   
2015-02-04 00:00:00  34.39   
2015-02-04 00:30:00  34.49   

Ответы [ 2 ]

0 голосов
/ 03 августа 2020

Одна из стратегий - добавить значения df.diff() в качестве нового столбца в ваш фрейм данных, а затем использовать метод df.apply() в каждой строке, чтобы вернуть либо исходное значение строки, либо NaN в зависимости от значения вновь добавленного diff столбец. Имейте в виду, что df.diff() вернет NaN для первой строки, поэтому вам нужно вручную учесть это в «функции выбора» в вашей функции apply.

df['diff'] = df.diff()
df['value column'] = df.apply(lambda x: x[0] if x[-1]<=100 or np.isnan(x[-1]) else np.nan , axis=1)
df

Результаты:

                     value column
index                            
2015-02-03 23:00:00         33.24
2015-02-03 23:30:00           NaN
2015-02-04 00:00:00         34.39
2015-02-04 00:30:00         34.49

0 голосов
/ 03 августа 2020

Вам нужно найти do diff сверху и вместе с ботом, иначе также выпадет строка номер 3

df["value column"].mask((df["value column"].diff(-1).abs()>100) & (df["value column"].diff().abs() > 100), np.nan) 
Out[270]: 
0    33.24
1      NaN
2    34.39
3    34.49
Name: value column, dtype: float64
...