删除具有N个或更多连续NaN的pandas数据帧中的所有行

时间:2018-06-12 05:07:40

标签: python pandas dataframe

这个问题的必然结果:replace values in pandas column when N number of NaNs exist in another column

         a         b         c     d           e
2018-05-25  0.000381  0.264318     land    2018-05-25
2018-05-26  0.000000  0.264447     land    2018-05-26
2018-05-27  0.000000  0.264791     NaN           NaT
2018-05-28  0.000000  0.265253     NaN           NaT
2018-05-29  0.000000  0.265720     NaN           NaT
2018-05-30  0.000000  0.266066     land    2018-05-30
2018-05-31  0.000000  0.266150     NaN           NaT
2018-06-01  0.000000  0.265816     NaN           NaT
2018-06-02  0.000000  0.264892     land    2018-06-02
2018-06-03  0.000000  0.263191     NaN           NaT
2018-06-04  0.000000  0.260508     land    2018-06-04
2018-06-05  0.000000  0.256619     NaN           NaT
2018-06-06  0.000000  0.251286     NaN           NaT
2018-06-07  0.000000  0.244250     NaN           NaT
2018-06-08  0.000000  0.235231     NaN           NaT
2018-06-09  0.000000  0.223932     land    2018-06-09

我想删除第4列(d)中有NaN 3次或更多次的所有行。输出应为:

         a         b         c     d           e
2018-05-25  0.000381  0.264318     land    2018-05-25
2018-05-26  0.000000  0.264447     land    2018-05-26
2018-05-30  0.000000  0.266066     land    2018-05-30
2018-05-31  0.000000  0.266150     NaN           NaT
2018-06-01  0.000000  0.265816     NaN           NaT
2018-06-02  0.000000  0.264892     land    2018-06-02
2018-06-03  0.000000  0.263191     NaN           NaT
2018-06-04  0.000000  0.260508     land    2018-06-04
2018-06-09  0.000000  0.223932     land    2018-06-09

从那个问题开始,我尝试了这个:

    threshold = 3
    mask = df.d.notna()
    df.loc[(~mask).groupby(mask.cumsum()).transform('cumsum') < threshold, 'c'] = np.nan
    df = df[np.isfinite(df['c'])]

但它不起作用

3 个答案:

答案 0 :(得分:4)

按连续值和transform include ld.so.conf.d/*.conf /usr/local/lib 创建帮助lddconfig a,最后按boolean indexing过滤:

Series

<强>详细

size
mask = df.d.notna()
a = mask.ne(mask.shift()).cumsum()

df = df[(a.groupby(a).transform('size') < 3) | mask]
print (df)
             a         b         c     d           e
0   2018-05-25  0.000381  0.264318  land  2018-05-25
1   2018-05-26  0.000000  0.264447  land  2018-05-26
5   2018-05-30  0.000000  0.266066  land  2018-05-30
6   2018-05-31  0.000000  0.266150   NaN         NaT
7   2018-06-01  0.000000  0.265816   NaN         NaT
8   2018-06-02  0.000000  0.264892  land  2018-06-02
9   2018-06-03  0.000000  0.263191   NaN         NaT
10  2018-06-04  0.000000  0.260508  land  2018-06-04
15  2018-06-09  0.000000  0.223932  land  2018-06-09

答案 1 :(得分:1)

这应该有效:

df = df.groupby(pd.notnull(df.d).cumsum()).apply(lambda x: x.dropna() if pd.isnull(x.d).sum() >= 3 else x).reset_index(drop=True)

输出:

            a         b         c     d           e
0  2018-05-25  0.000381  0.264318  land  2018-05-25
1  2018-05-26  0.000000  0.264447  land  2018-05-26
2  2018-05-30  0.000000  0.266066  land  2018-05-30
3  2018-05-31  0.000000  0.266150   NaN         NaT
4  2018-06-01  0.000000  0.265816   NaN         NaT
5  2018-06-02  0.000000  0.264892  land  2018-06-02
6  2018-06-03  0.000000  0.263191   NaN         NaT
7  2018-06-04  0.000000  0.260508  land  2018-06-04
8  2018-06-09  0.000000  0.223932  land  2018-06-09

答案 2 :(得分:0)

解决这个问题的一种方法,

df['seq'] = df.groupby(df['d'].notnull().cumsum())['a'].transform(len)
df=df[(df['seq']<4)|df['d'].notnull()]

输出:

             a         b         c     d           e  seq
0   2018-05-25  0.000381  0.264318  land  2018-05-25    1
1   2018-05-26  0.000000  0.264447  land  2018-05-26    4
5   2018-05-30  0.000000  0.266066  land  2018-05-30    3
6   2018-05-31  0.000000  0.266150   NaN         NaN    3
7   2018-06-01  0.000000  0.265816   NaN         NaN    3
8   2018-06-02  0.000000  0.264892  land  2018-06-02    2
9   2018-06-03  0.000000  0.263191   NaN         NaN    2
10  2018-06-04  0.000000  0.260508  land  2018-06-04    5
15  2018-06-09  0.000000  0.223932  land  2018-06-09    1