使用 Pandas DataFrame 按 nan 值的数量删除列

22

我有一个数据框,其中一些列包含nan。我想删除那些包含特定数量NaN的列。例如,在以下代码中,我想删除任何具有2个或更多NaN的列。在这种情况下,列“C”将被删除,只保留“A”和“B”。我该如何实现?

import pandas as pd
import numpy as np

dff = pd.DataFrame(np.random.randn(10,3), columns=list('ABC'))
dff.iloc[3,0] = np.nan
dff.iloc[6,1] = np.nan
dff.iloc[5:8,2] = np.nan

print dff
6个回答

37

dropna中有一个thresh参数,您只需要传递您的df长度减去您希望作为阈值的NaN值的数量即可:

In [13]:

dff.dropna(thresh=len(dff) - 2, axis=1)
Out[13]:
          A         B
0  0.517199 -0.806304
1 -0.643074  0.229602
2  0.656728  0.535155
3       NaN -0.162345
4 -0.309663 -0.783539
5  1.244725 -0.274514
6 -0.254232       NaN
7 -1.242430  0.228660
8 -0.311874 -0.448886
9 -0.984453 -0.755416

因此,上述代码将删除任何不符合数据框长度(行数)-2的非NaN值数量标准的列。


1
谢谢。你的代码中有一个错别字,len(df) 应该是 len(dff) - pyan
你知道是否可以仅对特定列的子集应用阈值吗?谢谢。 - pceccon
@pceccon 抱歉,我不太喜欢在评论中回答问题,因为缺乏清晰度。您可以通过传递列表来对列进行子集处理,所以如果我理解正确,您可以这样做:df[col_name_list].fillna(...),只将阈值应用于此子集,并将其应用于其他列 df[df.columns.difference(col_name_list)].filna(....) - EdChum

4
你可以使用条件列表推导式:
>>> dff[[c for c in dff if dff[c].isnull().sum() < 2]]
          A         B
0 -0.819004  0.919190
1  0.922164  0.088111
2  0.188150  0.847099
3       NaN -0.053563
4  1.327250 -0.376076
5  3.724980  0.292757
6 -0.319342       NaN
7 -1.051529  0.389843
8 -0.805542 -0.018347
9 -0.816261 -1.627026

这是一个在 CPU 方面高效的实现吗? - Victor Zuanazzi
对于大多数用例来说很简单,但答案取决于数据框的大小。在我的机器上,使用包含1百万行和3列的数据框时,接受的答案要快大约40%。 - Alexander

0

这里是一个可能的解决方案:

s = dff.isnull().apply(sum, axis=0) # count the number of nan in each column
print s
   A    1 
   B    1
   C    3
   dtype: int64

for col in dff: 
   if s[col] >= 2:  
       del dff[col]

或者

for c in dff:
    if sum(dff[c].isnull()) >= 2:
        dff.drop(c, axis=1, inplace=True)

0

我建议使用drop方法。这是另一种解决方案:

dff.drop(dff.loc[:,len(dff) - dff.isnull().sum() <2], axis=1)

0

您也可以通过另一种方法来删除具有特定数量的na值的列,如下所示:

df = df.drop( columns= [x for x in df if df[x].isna().sum() > 5 ])

删除具有特定缺失值百分比的列:

df = df.drop(columns= [x for x in df if round((df[x].isna().sum()/len(df)*100),2) > 20 ]) 

0

假设你需要删除包含超过70%空值的列。

data.drop(data.loc[:,list((100*(data.isnull().sum()/len(data.index))>70))].columns, 1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接