如何从具有多个名称相似的列的数据框的行中删除异常值?
How to remove outlier from rows of a data frame having multiple column with similar name?
我有一个包含多个列(大约 300,在这里我只发布了五个)的数据框,它们的名称相似,看起来像这样:
wave rv rv rv rv rv
4050.32 516.046391 1177.388115 291.478871 667.855218 139.966111
4512.99 523.027066 1121.650093 304.243851 366.686912 21.157569
4523.40 653.480487 1258.712111 565.797456 685.889408 211.022502
4551.65 543.679071 1170.182836 615.175059 538.739229 217.254275
4554.46 613.018264 1218.368040 512.241826 580.040475 148.860819
4555.49 660.986074 1310.192328 727.650639 652.957370 241.255968
现在,如果我尝试计算每一行的 MAD
或 MEDIAN
,它就会受到异常值的影响。
df['mean_rv']=df.rv.mean(axis=1)
df['mad_rv']=df.rv.mad(axis=1)
df['std_rv']=df.rv.std(axis=1)
df['median_rv']=df.rv.median(axis=1)
wave mean_rv mad_rv std_rv median_rv
4050.32 205.140781 515.455058 675.407100 402.282291
4512.99 185.022378 527.156411 694.815800 388.641627
4523.40 305.709437 508.197990 656.888951 565.797456
4551.65 245.231088 510.966951 663.052403 479.494050
4554.46 249.040192 546.425471 707.440193 496.937762
4555.49 354.556840 510.052320 658.062092 586.095377
那么如果我想从数据框中删除异常值怎么办呢?
您可以使用内四分位数范围 (IQR) 进行简单的离群值检测。来自维基百科
The interquartile range (IQR), also called the midspread or middle 50%, or technically H-spread, is a measure of statistical dispersion, being equal to the difference between 75th and 25th percentiles, or between upper and lower quartiles, IQR = Q3 − Q1.
In other words, the IQR is the first quartile subtracted from the third quartile; these quartiles can be clearly seen on a box plot on the data.
It is a measure of the dispersion similar to standard deviation or variance, but is much more robust against outliers.
Q1 = data.quantile(0.25)
Q3 = data.quantile(0.75)
IQR = Q3 - Q1
print(IQR)
if(data[i] < (Q1 - 1.5 * IQR)) |(data[i] > (Q3 + 1.5 * IQR))
#outlier detected
#do stuff ...
如果数据点位于异常值边界之外,则该数据点可能是异常值。因此,在您的情况下,根据逻辑,您也可以计算每列或所有列的异常值,这取决于您拥有的数据以及它们之间的相关性。希望能帮助到你。
顺便说一句,您可以使用 matplotlib boxplot
简单地形象化上述方法。只需传递你正在做离群值检测的一系列数据,它就会直接为你做并绘制出来。
还有其他方法,比如scikit learn outlier detection
这个blog也有用
就像您一般排除任何地方一样 - 通常根据 STD 定义阈值,然后应用过滤器:
mean = df.rv.mean(axis=1)
std = df.rv.std(axis=1)
new_mean = df.rv[abs(df.rv.subtract(mean,axis=0)).lt(std,axis=0)].mean(axis=1)
在lt
中你可以定义std
、2*std
等,这取决于异常值是什么。注意
df.rv[abs(df.rv.subtract(mean,axis=0)).lt(std,axis=0)]
将包含异常值所在的 nan
值,而 mean
和类似方法默认情况下会忽略这些值。
我有一个包含多个列(大约 300,在这里我只发布了五个)的数据框,它们的名称相似,看起来像这样:
wave rv rv rv rv rv
4050.32 516.046391 1177.388115 291.478871 667.855218 139.966111
4512.99 523.027066 1121.650093 304.243851 366.686912 21.157569
4523.40 653.480487 1258.712111 565.797456 685.889408 211.022502
4551.65 543.679071 1170.182836 615.175059 538.739229 217.254275
4554.46 613.018264 1218.368040 512.241826 580.040475 148.860819
4555.49 660.986074 1310.192328 727.650639 652.957370 241.255968
现在,如果我尝试计算每一行的 MAD
或 MEDIAN
,它就会受到异常值的影响。
df['mean_rv']=df.rv.mean(axis=1)
df['mad_rv']=df.rv.mad(axis=1)
df['std_rv']=df.rv.std(axis=1)
df['median_rv']=df.rv.median(axis=1)
wave mean_rv mad_rv std_rv median_rv
4050.32 205.140781 515.455058 675.407100 402.282291
4512.99 185.022378 527.156411 694.815800 388.641627
4523.40 305.709437 508.197990 656.888951 565.797456
4551.65 245.231088 510.966951 663.052403 479.494050
4554.46 249.040192 546.425471 707.440193 496.937762
4555.49 354.556840 510.052320 658.062092 586.095377
那么如果我想从数据框中删除异常值怎么办呢?
您可以使用内四分位数范围 (IQR) 进行简单的离群值检测。来自维基百科
The interquartile range (IQR), also called the midspread or middle 50%, or technically H-spread, is a measure of statistical dispersion, being equal to the difference between 75th and 25th percentiles, or between upper and lower quartiles, IQR = Q3 − Q1. In other words, the IQR is the first quartile subtracted from the third quartile; these quartiles can be clearly seen on a box plot on the data. It is a measure of the dispersion similar to standard deviation or variance, but is much more robust against outliers.
Q1 = data.quantile(0.25)
Q3 = data.quantile(0.75)
IQR = Q3 - Q1
print(IQR)
if(data[i] < (Q1 - 1.5 * IQR)) |(data[i] > (Q3 + 1.5 * IQR))
#outlier detected
#do stuff ...
如果数据点位于异常值边界之外,则该数据点可能是异常值。因此,在您的情况下,根据逻辑,您也可以计算每列或所有列的异常值,这取决于您拥有的数据以及它们之间的相关性。希望能帮助到你。
顺便说一句,您可以使用 matplotlib boxplot
简单地形象化上述方法。只需传递你正在做离群值检测的一系列数据,它就会直接为你做并绘制出来。
还有其他方法,比如scikit learn outlier detection
这个blog也有用
就像您一般排除任何地方一样 - 通常根据 STD 定义阈值,然后应用过滤器:
mean = df.rv.mean(axis=1)
std = df.rv.std(axis=1)
new_mean = df.rv[abs(df.rv.subtract(mean,axis=0)).lt(std,axis=0)].mean(axis=1)
在lt
中你可以定义std
、2*std
等,这取决于异常值是什么。注意
df.rv[abs(df.rv.subtract(mean,axis=0)).lt(std,axis=0)]
将包含异常值所在的 nan
值,而 mean
和类似方法默认情况下会忽略这些值。