过滤掉包含超过一定数量NaN的行

13 投票
3 回答
13174 浏览
提问于 2025-04-18 03:38

在一个Pandas的数据表中,我想要筛选掉所有有超过2个NaN的行。

简单来说,我有4列数据,我只想保留那些至少有2列是有效值的行。

有没有人能告诉我该怎么做呢?

3 个回答

0

我遇到了一个稍微不同的问题,也就是要筛选掉那些含有超过一定数量的NaN值的

import pandas as pd
import numpy as np

df = pd.DataFrame({'a':[1,2,np.nan,4,5], 'b':[np.nan,2,np.nan,4,5], 'c':[1,2,np.nan,np.nan,np.nan], 'd':[1,2,3,np.nan,5]})
df

    a   b   c   d
0   1.0 NaN 1.0 1.0
1   2.0 2.0 2.0 2.0
2   NaN NaN NaN 3.0
3   4.0 4.0 NaN NaN
4   5.0 5.0 NaN 5.0

假设你想筛选掉那些有3个或更多NaN值的列:

num_rows = df.shape[0]
drop_cols_with_this_amount_of_nans_or_more = 3
keep_cols_with_at_least_this_number_of_non_nans = num_rows - drop_cols_with_this_amount_of_nans_or_more + 1

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

输出结果:(列c已经被按预期删除):

    a   b   d
0   1.0 NaN 1.0
1   2.0 2.0 2.0
2   NaN NaN 3.0
3   4.0 4.0 NaN
4   5.0 5.0 5.0
16

你这里提了两个稍微不同的问题。在一般情况下,它们的答案是不一样的。

我想保留那些至少有2列有有效值的行。

df = df.dropna(thresh=2)

这个保留了有2个或更多非空值的行。


我想过滤掉所有有超过2个NaN的行。

df = df.dropna(thresh=df.shape[1]-2)

这个过滤掉了有2个或更多空值的行。

在你给的例子中,数据框有4列,这两个操作是等价的,因为df.shape[1] - 2 == 2。不过,如果数据框的列数不是正好4列,你会发现结果会有差别。


注意,dropna还有一个subset参数,如果你想在应用阈值时只包括特定的列,可以使用这个参数。例如:

df = df.dropna(subset=['col1', 'col2', 'col3'], thresh=2)
12

下面的代码应该可以正常工作

df.dropna(thresh=2)

可以查看在线文档

我们在这里做的事情是删除任何包含 NaN 的行,前提是这一行中有两个或更多的非 NaN 值。

举个例子:

In [25]:

import pandas as pd

df = pd.DataFrame({'a':[1,2,NaN,4,5], 'b':[NaN,2,NaN,4,5], 'c':[1,2,NaN,NaN,NaN], 'd':[1,2,3,NaN,5]})

df

Out[25]:

    a   b   c   d
0   1 NaN   1   1
1   2   2   2   2
2 NaN NaN NaN   3
3   4   4 NaN NaN
4   5   5 NaN   5

[5 rows x 4 columns]

In [26]:

df.dropna(thresh=2)

Out[26]:

   a   b   c   d
0  1 NaN   1   1
1  2   2   2   2
3  4   4 NaN NaN
4  5   5 NaN   5

[4 rows x 4 columns]

编辑

对于上面的例子,这个方法是有效的,但你需要知道列的数量,并相应地设置 thresh 的值。我最开始以为它是指 NaN 的数量,但实际上它是指 NaN 值的数量。

撰写回答