Я хотел бы удалить выбросы из кадра данных Pandas, используя некоторую пользовательскую функцию.Есть несколько ответов на тот же вопрос, который я задаю в Stackoverflow, но разница в том, что набор данных, который у меня есть, является циклическим.Поэтому использование встроенных функций Pandas mean()
, std()
не подходит.Например, в циклических данных значения 355
и 5
имеют только разницу 10, но линейная разница дает 350
.
У меня есть тысячи информационных фреймов, подобных приведенному ниже.Мы ясно видим, что Geophone
6 является выбросом.
Geophone azimuth incidence
0 1 194.765326 29.703151
1 2 193.143982 23.380681
2 3 199.327911 34.752212
3 4 195.641010 49.186893
4 5 193.479015 21.192982
5 6 0.745142 3.410046
6 7 192.380435 29.778807
7 8 196.700814 19.750237
Это также может быть подтверждено при построении данных на полярной диаграмме.
Я написал две функции mean_angle
и variance_angle
, который вычисляет среднее значение по кругу и дисперсию для применения к данным.Дисперсия дает значение от 0 до 1. Когда данные близки друг к другу, значение дисперсии становится ближе к 0 и наоборот.
import numpy as np
def mean_angle(deg):
deg = np.deg2rad(deg)
S = np.array(deg)
C = np.array(deg)
S = S[np.isfinite(S)] #remove np.nan
C = C[np.isfinite(C)]
S = np.sum(np.sin(S))
C = np.sum(np.cos(C))
mu = np.arctan(S/C)
mu = np.rad2deg(mu)
if S>0 and C>0:
mu = mu
elif S>0 and C<0:
mu = mu +180
elif S<0 and C<0:
mu = mu+180
elif S<0 and C>0:
mu = mu +360
return mu
def variance_angle(deg):
"""
deg: angles in degrees
"""
deg = np.deg2rad(deg)
S = np.array(deg)
C = np.array(deg)
S = S[np.isfinite(S)] #remove np.nan
C = C[np.isfinite(C)]
length = C.size
S = np.sum(np.sin(S))
C = np.sum(np.cos(C))
R = np.sqrt(S**2 + C**2)
R_avg = R/length
V = 1- R_avg
return V
mean_azimuth = mean_angle(df.azimuth)
variance = variance_angle(df.azimuth)
print(mean_azimuth)
197.4122778774279
print(variance)
0.24614383460498535
Однако, если исключить строку 5 из расчета, среднее значение и дисперсия становятся равными 195.06226604362286 , 0.0007544067627361928
соответственно.Дисперсия изменена с 0.25
до почти 0
.
. Поэтому я хотел бы найти способ удалить любое круговое значение выбросов / с (azimuth
), которое делает круговую дисперсию высокой, используя определенныефункции, показанные выше.
В этом примере incidence
также является выбросом для того же Geophone
, но фактически не имеет никакого отношения к azimuth
.Есть и другие данные, где incidence
находится в пределах диапазона, но azimuth
является выбросом.
Любая помощь действительно приветствуется.