如何根据上一行/下一行过滤熊猫行?

时间:2018-06-22 08:27:44

标签: python pandas numpy

我有两个来自不同脉搏血氧仪的数据集,并用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

sensor data from two pulse oximeters

2 个答案:

答案 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),并将先前的观察结果保留在闭包中以检测突然的变化,但这太复杂了。我会寻求直接的命令性解决方案。