删除在Python中包含NaN的行之前和之后的行?

时间:2019-05-24 12:17:27

标签: python pandas numpy dataframe

我正在尝试使用带有numpy和pandas的python清理实验数据。我的一些测量令人难以置信。我想从同一样本中删除这些测量以及前两个和后两个测量。我正在尝试找到一种优雅的方法来实现此目标,而无需使用for循环,因为我的数据帧非常大。

我的数据:

>>>df

    Date    Time    Sample  Measurement
index
7737    2019-04-15  06:40:00    A   6.560
7739    2019-04-15  06:50:00    A   1.063
7740    2019-04-15  06:55:00    A   1.136
7741    2019-04-15  07:00:00    A   1.301
7742    2019-04-15  07:05:00    A   1.435
7743    2019-04-15  07:10:00    A   1.704
7744    2019-04-15  07:15:00    A   1.961
7745    2019-04-15  07:20:00    A   2.023
7746    2019-04-15  07:25:00    A   6.284
7747    2019-04-15  07:30:00    A   2.253
7748    2019-04-15  07:35:00    A   6.549
7749    2019-04-15  07:40:00    A   2.591
7750    2019-04-15  07:45:00    A   6.321
7752    2019-04-15  07:55:00    A   0.937
7753    2019-04-15  08:00:00    B   0.372
7754    2019-04-15  08:05:00    B   0.382
7755    2019-04-15  08:10:00    B   0.390
7756    2019-04-15  08:15:00    B   0.455
7757    2019-04-15  08:20:00    B   6.499


import numpy as np
import pandas as pd 

df['Measurement'] = np.where(df['Measurement']>6.0, np.nan, df['Measurement'])

给予

>>>df

    Date    Time    Sample  Measurement
index
7737    2019-04-15  06:40:00    A   NaN
7739    2019-04-15  06:50:00    A   1.063
7740    2019-04-15  06:55:00    A   1.136
7741    2019-04-15  07:00:00    A   1.301
7742    2019-04-15  07:05:00    A   1.435
7743    2019-04-15  07:10:00    A   1.704
7744    2019-04-15  07:15:00    A   1.961
7745    2019-04-15  07:20:00    A   2.023
7746    2019-04-15  07:25:00    A   NaN
7747    2019-04-15  07:30:00    A   2.253
7748    2019-04-15  07:35:00    A   NaN
7749    2019-04-15  07:40:00    A   2.591
7750    2019-04-15  07:45:00    A   NaN
7752    2019-04-15  07:55:00    A   0.937
7753    2019-04-15  08:00:00    B   0.372
7754    2019-04-15  08:05:00    B   0.382
7755    2019-04-15  08:10:00    B   0.390
7756    2019-04-15  08:15:00    B   0.455
7757    2019-04-15  08:20:00    B   NaN

我使用

删除了行
df= df[np.isfinite(df['Measurement'])]

在删除样本中包含NaN的行之前和之后的2行之后,我试图获得结果(请注意,必须保留7753,因为此度量属于样本B)。


    Date    Time    Sample  Measurement
index
7741    2019-04-15  07:00:00    A   1.301
7742    2019-04-15  07:05:00    A   1.435
7743    2019-04-15  07:10:00    A   1.704
7753    2019-04-15  08:00:00    B   0.372
7754    2019-04-15  08:05:00    B   0.382


4 个答案:

答案 0 :(得分:3)

我们可以标记所有if view_func.__name__ in LOGIN_EXEMPT_URLS:前后的索引,然后将其值也替换为NaN

NaN

# Get indices of NaN's
idxnull = df[df['Measurement'].isnull()].index

a = [range(x+2) if x==0 else range(x-2, x) if x==idxnull.max() else range(x-2, x+2) for x in idxnull]

for rng in a:
    df.loc[rng, 'Measurement'] = np.NaN

df.dropna(inplace=True)
df = df.iloc[1:]

列表理解似乎很困难,但是有以下内容:

    Index        Date      Time Sample  Measurement
3    7741  2019-04-15  07:00:00      A        1.301
4    7742  2019-04-15  07:05:00      A        1.435
5    7743  2019-04-15  07:10:00      A        1.704
14   7753  2019-04-15  08:00:00      B        0.372
15   7754  2019-04-15  08:05:00      B        0.382

答案 1 :(得分:2)

首先,我将您标记为无效者,其他地方是NaN,然后​​是bfillffill

df['invalid'] = np.where(df.Measurement.gt(6), True, np.nan)
groups = df.groupby('Sample')

df['invalid'] = groups.invalid.ffill(limit=2)
df['invalid'] = groups.invalid.bfill(limit=2)

# drop the invalids:
df = df[df.invalid.isna()]

# drop the invalid column:
df.drop('invalid', axis=1, inplace=True)

输出:

        Date        Time    Sample  Measurement
Index               
7741    2019-04-15  07:00:00    A   1.301
7742    2019-04-15  07:05:00    A   1.435
7743    2019-04-15  07:10:00    A   1.704
7753    2019-04-15  08:00:00    B   0.372
7754    2019-04-15  08:05:00    B   0.382

答案 2 :(得分:1)

df.loc[((df['Measurement']>6) & (df['Sample'] == 'A')),'drop'] = 'Y'

# making sure B readings dont get dropped

l = df.index[df['drop'] == 'Y'].tolist()
l_drop = []
for i in l:
    l_drop.append(i-1)
    l_drop.append(i+1)
    l_drop.append(i+2)

df.drop(df.index[l_drop],inplace=True)

不迭代数据框。

答案 3 :(得分:0)

您可以通过设置 center = True 并将窗口大小设置为 5 来尝试Seies.rolling(),例如:

m = df.groupby('Sample').Measurement \
      .rolling(5, center=True, min_periods=1) \
      .apply(lambda x: x.isna().any(), raw=False) \
      .reset_index(level=0, drop=True) \
      .eq(0)

print(df[m])
#            Date      Time Sample  Measurement
#7741  2019-04-15  07:00:00      A        1.301
#7742  2019-04-15  07:05:00      A        1.435
#7743  2019-04-15  07:10:00      A        1.704
#7753  2019-04-15  08:00:00      B        0.372
#7754  2019-04-15  08:05:00      B        0.382

您可以将x.isna().any()调整为x.gt(6.0).any(),这样就无需在“测量”列上设置NaN值。