在 pandas 数据框中检索 NaN 值的索引

Posted

技术标签:

【中文标题】在 pandas 数据框中检索 NaN 值的索引【英文标题】:Retrieve indices of NaN values in a pandas dataframe 【发布时间】:2016-02-11 23:51:26 【问题描述】:

我尝试为包含 NaN 值的每一行检索相应列的所有索引。

d=[[11.4,1.3,2.0, NaN],[11.4,1.3,NaN, NaN],[11.4,1.3,2.8, 0.7],[NaN,NaN,2.8, 0.7]]
df = pd.DataFrame(data=d, columns=['A','B','C','D'])
print df

      A    B    C    D
0  11.4  1.3  2.0  NaN
1  11.4  1.3  NaN  NaN
2  11.4  1.3  2.8  0.7
3  NaN   NaN  2.8  0.7

我已经做了以下事情:

为每一行添加一个包含 NaN 计数的列 获取包含 NaN 值的每一行的索引

我想要的(最好是列的名称)是得到一个这样的列表:

[ ['D'],['C','D'],['A','B'] ]

希望我能找到一种方法,而无需对每一行进行每一列的测试

if df.ix[i][column] == NaN:

我正在寻找一种能够处理我的庞大数据集的熊猫方式。

提前致谢。

【问题讨论】:

我已经找到了包含 NaN 值的每一行的索引。我想要的是每行的列索引。如果描述不清楚,请见谅。 【参考方案1】:

使用 scipy 坐标格式的稀疏矩阵来检索空值的坐标应该是有效的:

import scipy.sparse as sp

x,y = sp.coo_matrix(df.isnull()).nonzero()
print(list(zip(x,y)))

[(0, 3), (1, 2), (1, 3), (3, 0), (3, 1)]

请注意,我调用 nonzero 方法只是为了输出底层稀疏矩阵中非零条目的坐标,因为我不关心全部为 True 的实际值。

【讨论】:

这个解决方案比@Alexander 的快 2 倍,但我不知道如何在这种数据中导航。它不像列表那么容易【参考方案2】:

您可以遍历数据框中的每一行,创建空值掩码,并输出它们的索引(即数据框中的列)。

lst = []
for _, row in df.iterrows():
    mask = row.isnull()
    lst += [row[mask].index.tolist()]

>>> lst
[['D'], ['C', 'D'], [], ['A', 'B']]

【讨论】:

【参考方案3】:

另一种方法,提取为 NaN 的行:

In [11]: df_null = df.isnull().unstack()

In [12]: t = df_null[df_null]

In [13]: t
Out[13]:
A  3    True
B  3    True
C  1    True
D  0    True
   1    True
dtype: bool

这可以帮助您完成大部分工作,并且可能就足够了。 虽然使用系列可能更容易:

In [14]: s = pd.Series(t2.index.get_level_values(1), t2.index.get_level_values(0))

In [15]: s
Out[15]:
0    D
1    C
1    D
3    A
3    B
dtype: object

例如如果你想要这些列表(尽管我认为你不需要它们)

In [16]: s.groupby(level=0).apply(list)
Out[16]:
0       [D]
1    [C, D]
3    [A, B]
dtype: object

【讨论】:

这显然是最“受欢​​迎”的方式,但比 @maxymoo 慢 100 倍 @dooms 你的意思是申请吗? 这很令人惊讶,主要是因为接受的答案是 O(n^2)。我可以看到应用部分很慢,但正如我所说,我认为你真的不需要那个部分。 您对我的整个数据集的解决方案比第一个解决方案要快得多。复杂性你说得对!【参考方案4】:

另一种更简单的方法是:

>>>df.isnull().any(axis=1)
0     True
1     True
2    False
3     True
dtype: bool

到子集:

>>> bool_idx = df.isnull().any(axis=1)
>>> df[bool_idx]
    A         B     C    D
0   11.4    1.3     2.0  NaN
1   11.4    1.3     NaN  NaN
3   NaN      NaN    2.8  0.7

获取整数索引:

>>> df[bool_idx].index
Int64Index([0, 1, 3], dtype='int64')

【讨论】:

【参考方案5】:

尝试使用:

s = df.isna().any()

它返回一系列布尔值,表示列具有NaN 值。索引是列名。

然后您使用

检索 NaN
s[s==True].index[0]

【讨论】:

以上是关于在 pandas 数据框中检索 NaN 值的索引的主要内容,如果未能解决你的问题,请参考以下文章

在 pandas 数据框中显示具有一个或多个 NaN 值的行

查找具有 NaN 值的 DataFrame 列表的索引 - Pandas

从 Pandas 的索引中检索列的名称

替换数据框中的 NaN 索引值

用相关列的平均值替换数据框中的 NaN 值的函数

通过 Pandas 中的函数替换 NaN 时索引超出范围