【问题标题】:Pandas: How to detect the peak points (outliers) in a dataframe?Pandas:如何检测数据框中的峰值点(异常值)?
【发布时间】:2018-12-03 00:10:39
【问题描述】:

我有一个带有几个速度值的熊猫数据框,这些速度值是连续移动的,但它是一个传感器数据,所以我们经常在中间得到错误,在某些点移动平均值似乎也无济于事,所以呢我可以使用哪些方法从数据中删除这些异常值或峰值点?

例子:

data points = {0.5,0.5,0.7,0.6,0.5,0.7,0.5,0.4,0.6,4,0.5,0.5,4,5,6,0.4,0.7,0.8,0.9}

在这个数据中如果我看到点 4、4、5、6 完全是异常值, 在我使用带有 5 分钟窗框的滚动平均值来平滑这些值之前,但我仍然得到了这些类型的很多光点,我想删除这些光点,任何人都可以建议我任何技术来摆脱这些点.

我有一张更清晰的数据视图:

如果您在这里看到数据如何显示一些我必须删除的异常点? 任何想法有什么可能的方法来摆脱这些点?

【问题讨论】:

  • 您可以计算所有点的 z 分数并拒绝超过某个阈值。
  • @ALollz 适用于正态分布在两边的情况,但在这里我不会有任何低于零的值,或者速度永远不会变成负数,仍然是正确的技术在这种情况下使用 z-score ...???
  • 哦,好点,那数据会不正常。您是否根据经验了解基础分布应该是什么?
  • 这里有一个可能有用的链接:outlier detection on skewed distributions

标签: python python-3.x pandas outliers


【解决方案1】:

您可以按如下方式削减某个分位数以上的值:

import numpy as np
clean_data=np.array(data_points)[(data_points<=np.percentile(data_points, 95))]

在 pandas 中你会使用df.quantile,你可以找到它here

或者您可以使用 Q3+1.5*IQR 方法来消除异常值,就像您通过箱线图所做的那样

【讨论】:

  • 我之前使用了这两种技术,但似乎无法处理我的数据,这就是为什么我仍在尝试找出仅取出那些最高点的另一种好技术。我使用了z-score,也使用了IQR方法来去掉这些点。
【解决方案2】:

我真的认为使用scipy.stats.zscore() 的z-score 是这里的方法。查看this post 中的相关问题。在那里,他们专注于在删除潜在异常值之前使用哪种方法。在我看来,您的挑战有点简单,因为从提供的数据来看,无需转换数据即可识别潜在的异常值非常简单。下面是一个代码 sn-p 就是这样做的。但请记住,什么看起来像异常值和看起来不像异常值将完全取决于您的数据集。在移除 一些 异常值之后,以前看起来不像异常值的东西,现在突然变得如此。看看:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy import stats

# your data (as a list)
data = [0.5,0.5,0.7,0.6,0.5,0.7,0.5,0.4,0.6,4,0.5,0.5,4,5,6,0.4,0.7,0.8,0.9]

# initial plot
df1 = pd.DataFrame(data = data)
df1.columns = ['data']
df1.plot(style = 'o')

# Function to identify and remove outliers
def outliers(df, level):

    # 1. temporary dataframe
    df = df1.copy(deep = True)

    # 2. Select a level for a Z-score to identify and remove outliers
    df_Z = df[(np.abs(stats.zscore(df)) < level).all(axis=1)]
    ix_keep = df_Z.index

    # 3. Subset the raw dataframe with the indexes you'd like to keep
    df_keep = df.loc[ix_keep]

    return(df_keep)

原始数据:

测试运行 1:Z 分数 = 4:

如您所见,没有数据被删除,因为级别设置得太高了。

测试运行 2:Z 分数 = 2:

现在我们正在取得进展。两个异常值已被移除,但仍有一些可疑数据。

测试运行 3:Z 分数 = 1.2:

这看起来真的很好。剩下的数据现在似乎比以前分布得更均匀了。但现在原始数据点突出显示的数据点开始看起来有点像潜在的异常值。那么该停在哪里呢?这完全取决于您!

编辑:这是一个简单的复制和粘贴的全部内容:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy import stats

# your data (as a list)
data = [0.5,0.5,0.7,0.6,0.5,0.7,0.5,0.4,0.6,4,0.5,0.5,4,5,6,0.4,0.7,0.8,0.9]

# initial plot
df1 = pd.DataFrame(data = data)
df1.columns = ['data']
df1.plot(style = 'o')

# Function to identify and remove outliers
def outliers(df, level):

    # 1. temporary dataframe
    df = df1.copy(deep = True)

    # 2. Select a level for a Z-score to identify and remove outliers
    df_Z = df[(np.abs(stats.zscore(df)) < level).all(axis=1)]
    ix_keep = df_Z.index

    # 3. Subset the raw dataframe with the indexes you'd like to keep
    df_keep = df.loc[ix_keep]

    return(df_keep)

# remove outliers
level = 1.2
print("df_clean = outliers(df = df1, level = " + str(level)+')')
df_clean = outliers(df = df1, level = level)

# final plot
df_clean.plot(style = 'o')

【讨论】:

  • @id101112 这解决了您的问题吗?如果现在告诉我,我会再看一遍。
  • 抱歉回复晚了,我确实在使用 zscore 方法,但我以不同的方式工作,非常感谢您的友好回复
猜你喜欢
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 2018-03-04
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 2018-03-29
相关资源
最近更新 更多