我有两个来自不同脉搏血氧仪的数据集,并用pyplot对其进行绘制,如下所示。如您所见,绿色数据表中有很多异常值(垂直滴)。在我的工作中,我将这些外层定义为对我的统计分析无效,因此这些外层一定不是测量值。因此,我认为我可以简单地删除它们。
这些流氓值的特征是它们是单个(或前两个)值离群值(请参见下面的df)。 “实际”样本值与先前的值相同或为+ -1。例如java(伪代码)我会做类似的事情:
for(i; i <df.length; i++)
if (df[i+1|-1].spo2 - df[i].spo2 > 1|-1)
df[i].drop
将pandas(numpy?)等同于我要执行的操作,删除与上一个/下一个值相比大于/小于1的值吗?
df:
time, spo2
1900-01-01 18:18:41.194 98.0
1900-01-01 18:18:41.376 98.0
1900-01-01 18:18:41.559 78.0
1900-01-01 18:18:41.741 98.0
1900-01-01 18:18:41.923 98.0
1900-01-01 18:18:42.105 90.0
1900-01-01 18:18:42.288 97.0
1900-01-01 18:18:42.470 97.0
1900-01-01 18:18:42.652 98.0
答案 0 :(得分:2)
看看pandas.DataFrame.shift。这是按列操作,将给定列中的所有行移至另一列的另一行:
# original df
x1
0 0
1 1
2 2
3 3
4 4
# shift down
df.x2 = df.x1.shift(1)
x1 x2
0 0 NaN # Beware
1 1 0
2 2 1
3 3 2
4 4 3
# Shift up
df.x2 = df.x1.shift(-1)
x1 x2
0 0 1
1 1 2
2 2 3
3 3 4
4 4 NaN # Beware
您可以使用此操作将时间戳spo2
中的n+1
的{{1}}移动到时间戳spo2
行中的n
旁边。然后,根据应用于该行的条件进行过滤。
df['spo2_Next'] = df['spo2'].shift(-1)
# replace NaN to allow float comparison
df.spo2_Next.fillna(1, inplace = True)
# Apply your row-wise condition to create filter column
df.loc[((df.spo2_Next - df.spo2) > 1) or ((df.spo2_Next - df.spo2) < 1), 'Outlier'] = True
# filter
df_clean = df[df.Outlier != True]
# remove filter column
del df_clean['Outlier']
答案 1 :(得分:1)
当您过滤像这样的熊猫数据框时:
df [df.colum1 = 2&df.colum2 <3],您是:
因此,您只需要在数据框上创建一个迭代算法来生成这种布尔数组,并使用它来过滤数据框,如下所示:
import pandas as pd
data = [['Alex',10],['Bob',12],['Clarke',13]]
df = pd.DataFrame(data,columns=['Name','Age'])
df[ [True, False, True]]
您还可以创建一个用于过滤数据帧的闭包(使用df.apply),并将先前的观察结果保留在闭包中以检测突然的变化,但这太复杂了。我会寻求直接的命令性解决方案。