【问题标题】:Retrieve indices of NaN values in a pandas dataframe在 pandas 数据框中检索 NaN 值的索引
【发布时间】: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 值的每一行的索引。我想要的是每行的列索引。如果描述不清楚,请见谅。

标签: python pandas machine-learning


【解决方案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]
      

      【讨论】:

        猜你喜欢
        • 2020-04-11
        • 1970-01-01
        • 2017-04-22
        • 2016-01-03
        • 2020-10-22
        • 2020-06-21
        • 1970-01-01
        • 2012-12-10
        • 1970-01-01
        相关资源
        最近更新 更多