Как отфильтровать строки панд на основе последней / следующей строки?

1

У меня есть два набора данных из разных пульсоксиметров, и выстройте их с помощью pyplot, как показано ниже. Как вы можете видеть, зеленый лист данных имеет много выбросов (вертикальные капли). В своей работе я определил эти затраты как недействительные для моего статистического анализа, они, безусловно, не должны быть измерениями. Поэтому я утверждаю, что могу просто удалить их.

Характеристики этих значений изгоев - это одиночные (или верхние два) значения outliers (см. Ниже 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 по сравнению с последним/следующим значением?


ДФ:

    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

Изображение 174551

Теги:
pandas
numpy

2 ответа

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 рядом с spo2 в строке timestamp 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

Когда вы фильтруете рамку данных pandas, например:

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) и сохранить предыдущие наблюдения в закрытии для обнаружения резких изменений, но это было бы слишком сложно. Я бы выбрал прямое императивное решение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню