2017-10-17 146 views
0

我有一個用於快速傅立葉變換信號的DataFrame。使用滾動標準偏差檢測Pandas數據框中的離羣值

有一列頻率爲Hz,另一列爲相應的幅度。

我讀過幾年前發佈的一篇文章,您可以使用簡單的布爾函數來排除或僅包含最終數據框中高於或低於幾個標準偏差的異常值。

df = pd.DataFrame({'Data':np.random.normal(size=200)}) # example dataset of normally distributed data. 
df[~(np.abs(df.Data-df.Data.mean())>(3*df.Data.std()))] # or if you prefer the other way around 

的問題是,我的信號下降幾個數量級(最多小10 000倍),其頻率的增加可達50 000Hz。因此,我無法使用僅輸出高於3個標準差的值的函數,因爲我只會從前50赫茲中挑選出「峯值」異常值。

有沒有一種方法可以在我的數據框中導出超出滾動平均值的3個滾動標準偏差的異常值?

+0

所以我想在導出之前將所有過濾的值(大於我的平均值+ 3SD)添加到我的數據框中的另一列中。現在他們只顯示爲真或假,從'N1 ['Peaks'] =(N1 ['Cell 1-1']> N1 ['Filter'])'有沒有辦法得到數字呢?單元格1-1和過濾器只是我的數據和過濾器的值。 – Jack

回答

0

這可能是一個很好的例子。基本上,您將現有數據與滾動平均值加上三個標準偏差的新列進行比較,滾動平均值也是如此。

import pandas as pd 
import numpy as np 
np.random.seed(123) 
df = pd.DataFrame({'Data':np.random.normal(size=200)}) 

# Create a few outliers (3 of them, at index locations 10, 55, 80) 
df.iloc[[10, 55, 80]] = 40.  

r = df.rolling(window=20) # Create a rolling object (no computation yet) 
mps = r.mean() + 3. * r.std() # Combine a mean and stdev on that object 

print(df[df.Data > mps.Data]) # Boolean filter 
#  Data 
# 55 40.0 
# 80 40.0 

要將新的列過濾僅添加到異常值,與NaN的別處:

df['Peaks'] = df['Data'].where(df.Data > mps.Data, np.nan) 

print(df.iloc[50:60]) 
     Data Peaks 
50 -1.29409 NaN 
51 -1.03879 NaN 
52 1.74371 NaN 
53 -0.79806 NaN 
54 0.02968 NaN 
55 40.00000 40.0 
56 0.89071 NaN 
57 1.75489 NaN 
58 1.49564 NaN 
59 1.06939 NaN 

這裏.where返回

相同形狀的一個目的爲self和其對應的條目是 從self其中cond是正確的,否則是從other