pandas 如何根据数据帧的 NAN 百分比删除列?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43311555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 03:21:46  来源:igfitidea点击:

How to drop column according to NAN percentage for dataframe?

pythonpandasdataframenan

提问by LookIntoEast

For certain columns of df, if 80% of the column is NAN.

对于 的某些列df,如果该列的 80% 是NAN.

What's the simplest code to drop such columns?

删除此类列的最简单代码是什么?

回答by jezrael

You can use isnullwith meanfor treshold and then remove columns by boolean indexingwith loc(because remove columns), also need invert condition - so <.8means remove all columns >=0.8:

您可以使用isnullwith meanfor treshold 然后通过boolean indexingwith删除列loc(因为删除列),也需要反转条件 - 所以<.8意味着删除所有列>=0.8

df = df.loc[:, df.isnull().mean() < .8]

Sample:

样本:

np.random.seed(100)
df = pd.DataFrame(np.random.random((100,5)), columns=list('ABCDE'))
df.loc[:80, 'A'] = np.nan
df.loc[:5, 'C'] = np.nan
df.loc[20:, 'D'] = np.nan

print (df.isnull().mean())
A    0.81
B    0.00
C    0.06
D    0.80
E    0.00
dtype: float64

df = df.loc[:, df.isnull().mean() < .8]
print (df.head())
         B   C         E
0  0.278369 NaN  0.004719
1  0.670749 NaN  0.575093
2  0.209202 NaN  0.219697
3  0.811683 NaN  0.274074
4  0.940030 NaN  0.175410

If want remove columns by minimal values dropnaworking nice with parameter threshand axis=1for remove columns:

如果想通过dropna与参数配合良好的最小值删除列threshaxis=1删除列:

np.random.seed(1997)
df = pd.DataFrame(np.random.choice([np.nan,1], p=(0.8,0.2),size=(10,10)))
print (df)
     0   1    2    3    4    5    6    7   8    9
0  NaN NaN  NaN  1.0  1.0  NaN  NaN  NaN NaN  NaN
1  1.0 NaN  1.0  NaN  NaN  NaN  NaN  NaN NaN  NaN
2  NaN NaN  NaN  NaN  NaN  1.0  1.0  NaN NaN  NaN
3  NaN NaN  NaN  NaN  1.0  NaN  NaN  NaN NaN  NaN
4  NaN NaN  NaN  NaN  NaN  1.0  NaN  NaN NaN  1.0
5  NaN NaN  NaN  1.0  1.0  NaN  NaN  1.0 NaN  1.0
6  NaN NaN  NaN  NaN  NaN  NaN  NaN  NaN NaN  NaN
7  NaN NaN  NaN  NaN  NaN  NaN  NaN  NaN NaN  NaN
8  NaN NaN  NaN  NaN  NaN  NaN  NaN  1.0 NaN  NaN
9  1.0 NaN  NaN  NaN  1.0  NaN  NaN  1.0 NaN  NaN

df1 = df.dropna(thresh=2, axis=1)
print (df1)
     0    3    4    5    7    9
0  NaN  1.0  1.0  NaN  NaN  NaN
1  1.0  NaN  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  1.0  NaN  NaN
3  NaN  NaN  1.0  NaN  NaN  NaN
4  NaN  NaN  NaN  1.0  NaN  1.0
5  NaN  1.0  1.0  NaN  1.0  1.0
6  NaN  NaN  NaN  NaN  NaN  NaN
7  NaN  NaN  NaN  NaN  NaN  NaN
8  NaN  NaN  NaN  NaN  1.0  NaN
9  1.0  NaN  1.0  NaN  1.0  NaN

EDIT: For non-Boolean data

编辑:对于非布尔数据

Total number of NaN entries in a column must be less than 80% of total entries:

列中 NaN 条目的总数必须小于总条目的 80%:

 df = df.loc[:, df.isnull().sum() < 0.8*df.shape[0]]

回答by Stephen Rauch

As suggested in comments, if you use sum()on a boolean test, you can get the number of occurences.

正如评论中所建议的,如果您sum()在布尔测试中使用,您可以获得出现次数。

Code:

代码:

def get_nan_cols(df, nan_percent=0.8):
    threshold = len(df.index) * nan_percent
    return [c for c in df.columns if sum(df[c].isnull()) >= threshold]  

Used as:

用作:

del df[get_nan_cols(df, 0.8)]

回答by rakesh

df.dropna(thresh=np.int((100-percent_NA_cols_required)*(len(df.columns)/100)),inplace=True)

Basically pd.dropna takes number(int) of non_na cols required if that row is to be removed.

如果要删除该行,基本上 pd.dropna 需要 number(int) 的 non_na cols。