【问题标题】:Find Indexes of Non-NaN Values in Pandas DataFrame在 Pandas DataFrame 中查找非 NaN 值的索引
【发布时间】:2017-04-30 05:37:02
【问题描述】:

我有一个非常大的数据集(大约 200000x400),但是我对其进行了过滤,只剩下几百个值,其余的是 NaN。我想创建这些剩余值的索引列表。我似乎找不到足够简单的解决方案。

    0     1     2
0   NaN   NaN   1.2
1   NaN   NaN   NaN   
2   NaN   1.1   NaN   
3   NaN   NaN   NaN
4   1.4   NaN   1.01

例如,我想要一个 [(0,2), (2,1), (4,0), (4,2)] 的列表。

【问题讨论】:

标签: python-2.7 pandas dataframe


【解决方案1】:

将数据框转换为等效的 NumPy 数组表示并检查 NaNs 是否存在。稍后,使用numpy.argwhere 取反它的相应索引(表示非空值)。由于所需的输出必须是元组列表,因此您可以使用生成器 map 函数将 tuple 作为函数应用于结果数组的每个可迭代对象。

>>> list(map(tuple, np.argwhere(~np.isnan(df.values))))
[(0, 2), (2, 1), (4, 0), (4, 2)]

【讨论】:

    【解决方案2】:

    假设您的列名是int dtype:

    In [73]: df
    Out[73]:
         0    1     2
    0  NaN  NaN  1.20
    1  NaN  NaN   NaN
    2  NaN  1.1   NaN
    3  NaN  NaN   NaN
    4  1.4  NaN  1.01
    
    In [74]: df.columns.dtype
    Out[74]: dtype('int64')
    
    In [75]: df.stack().reset_index().drop(0, 1).apply(tuple, axis=1).tolist()
    Out[75]: [(0, 2), (2, 1), (4, 0), (4, 2)]
    

    如果您的列名是object dtype:

    In [81]: df.columns.dtype
    Out[81]: dtype('O')
    
    In [83]: df.stack().reset_index().astype(int).drop(0,1).apply(tuple, axis=1).tolist()
    Out[83]: [(0, 2), (2, 1), (4, 0), (4, 2)]
    

    50K 行 DF 的时间:

    In [89]: df = pd.concat([df] * 10**4, ignore_index=True)
    
    In [90]: df.shape
    Out[90]: (50000, 3)
    
    In [91]: %timeit list(map(tuple, np.argwhere(~np.isnan(df.values))))
    10 loops, best of 3: 144 ms per loop
    
    In [92]: %timeit df.stack().reset_index().drop(0, 1).apply(tuple, axis=1).tolist()
    1 loop, best of 3: 1.67 s per loop
    

    结论:Nickil Maveli's solution 在这个测试 DF 中快了 12 倍

    【讨论】:

      猜你喜欢
      • 2017-12-31
      • 2014-11-26
      • 1970-01-01
      • 2016-10-06
      • 2017-07-12
      • 2018-03-19
      • 2015-01-25
      • 1970-01-01
      • 2019-10-20
      相关资源
      最近更新 更多