2017-09-20 34 views
2

我想知道是否有一种考虑的方法可以排除所有多于的列N NaN,从该子集中排除一列。具有> N个NaN的滴列不包括特定列

例如:

df = pd.DataFrame([[np.nan, 2, np.nan, 0], 
        [3, 4, np.nan, 1], 
        [np.nan, np.nan, np.nan, 5]], 
        columns=list('ABCD')) 

结果:

A B C D 
0 NaN 2.0 NaN 0 
1 3.0 4.0 NaN 1 
2 NaN NaN NaN 5 

运行下面,我得到:

df.dropna(thresh=2, axis=1) 

    B D 
0 2.0 0 
1 4.0 1 
2 NaN 5 

我想继续列 'C'。即,除了在'C'列之外执行这个阈值。

这可能吗?

回答

3

一旦完成阈值处理,就可以放回列。如果你在一行中完成这一切,则甚至不需要存储对该列的引用。

import pandas as pd 
import numpy as np 

df = pd.DataFrame([[np.nan, 2, np.nan, 0], 
        [3, 4, np.nan, 1], 
        [np.nan, np.nan, np.nan, 5]], 
        columns=list('ABCD')) 
df.dropna(thresh=2, axis=1).assign(C=df['C']) 

你也可以做

C = df['C'] 
df.dropna(thresh=2, axis=1) 
df.assign(C=C) 

正如@Wen建议,你也可以做一个索引操作,不会删除C列开始。

threshold = 2 
df = df.loc[:, (df.isnull().sum(0) < threshold) | (df.columns == 'C')] 

这里列的索引将选择具有少于thresholdNaN值,或他的名字是C列。如果您想在例外中包含多个列,则可以使用“或”运算符|链接更多条件。例如:

df = df.loc[ 
    :, 
    (df.isnull().sum(0) < threshold) | 
    (df.columns == 'C') | 
    (df.columns == 'D')] 
2
df.loc[:,(df.isnull().sum(0)<=1)|(df.isnull().sum(0)==len(df))] 
Out[415]: 
    B C D 
0 2.0 NaN 0 
1 4.0 NaN 1 
2 NaN NaN 5 

按零的建议

df.loc[:,(df.isnull().sum(0)<=1)|(df.isnull().all(0))] 

编辑:

df.loc[:,(df.isnull().sum(0)<=1)|(df.columns=='C')] 
+0

'df.isnull()。所有(0)'代替'df.isnull()。总和(0)== LEN(DF)'? – Zero

+0

@零增加,:) – Wen

+0

这是不正确的 - 它只适用于这个例子,因为C是唯一具有所有'NaN'的列。这将保留任何具有所有'NaN'的列,而不一定是C列(如果C没有全部'NaN')。 –

2

,融合了来自其他答案的一些概念另取。

df.loc[:, df.isnull().assign(C=False).sum().lt(2)] 

    B C D 
0 2.0 NaN 0 
1 4.0 NaN 1 
2 NaN NaN 5