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

7

我尝试检索每个包含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:

我正在寻找一种使用pandas处理大型数据集的方法。
提前感谢。

我已经找到了每行包含NaN值的索引。我想要的是每行对应的列的索引。如果描述不清楚,很抱歉。 - dooms
5个回答

5

使用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的快两倍,但我不知道如何在这种数据中导航。它不像列表那么容易。 - dooms

3
另一种方法是提取NaN行: ```

另一种方法是提取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

这可以让你完成大部分工作,可能已经足够了。
虽然使用Series可能更容易:

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
@dooms 你是指执行 apply 操作吗? - Andy Hayden
这非常令人惊讶,主要是因为被接受的答案是O(n^2)。我可以看到应用程序部分很慢,但是我认为您实际上并不需要那部分。 - Andy Hayden
你的解决方案对于我的整个数据集比第一个要快得多。你关于复杂性的观点是正确的! - dooms

3

另一种更简单的方法是:

>>>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')

1
你可以遍历数据框中的每一行,创建一个空值掩码,并输出它们的索引(即数据框中的列)。
lst = []
for _, row in df.iterrows():
    mask = row.isnull()
    lst += [row[mask].index.tolist()]

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

0

请尝试使用:

s = df.isna().any()

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

然后,您可以使用以下方法检索NaN列:

s[s==True].index[0]

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