【问题标题】:Ignoring -Inf values in arrays using numpy/scipy in Python在 Python 中使用 numpy/scipy 忽略数组中的 -Inf 值
【发布时间】:2010-12-19 23:37:38
【问题描述】:

我在 numpy 中有一个 NxM 数组,我想记录它,并忽略记录之前为负的条目。当我记录负数时,它会返回 -Inf,因此我将得到一个包含一些 -Inf 值的矩阵。然后我想对这个矩阵的列求和,但忽略 -Inf 值——我该怎么做?

例如,

mylogarray = log(myarray)
# take sum, but ignore -Inf?
sum(mylogarray, 0)

我知道有 nansum,我需要类似的东西,比如 infsum。

谢谢。

【问题讨论】:

    标签: python numpy scipy


    【解决方案1】:

    最简单的方法是使用numpy.ma.masked_invalid():

    a = numpy.log(numpy.arange(15))
    a.sum()
    # -inf
    numpy.ma.masked_invalid(a).sum()
    # 25.19122118273868
    

    【讨论】:

    • 如果你仍然有 sum 结果 inf 即使使用掩码,请尝试将 dtype 更改为 np.float64
    • 这帮助我从平均计算中过滤掉np.inf...谢谢!
    【解决方案2】:

    使用masked arrays:

    >>> a = numpy.array([2, 0, 1.5, -3])
    >>> b = numpy.ma.log(a)
    >>> b
    masked_array(data = [0.69314718056 -- 0.405465108108 --],
                 mask = [False  True False  True],
           fill_value = 1e+20)
    
    >>> b.sum()
    1.0986122886681096
    

    【讨论】:

    • 您能详细说明一下吗?我不明白这个例子。上面的屏蔽数组是怎么初始化的?
    • @user248237 - numpy.ma.log 等函数将自动创建一个屏蔽数组,其中任何导致 infnan 的内容都被屏蔽。不过,这有点不明确,因此您可以改为这样做:a = np.ma.masked_where(a == np.inf, a),然后只需执行b = np.log(a)(或任何其他函数)。或者,您可以避免使用掩码数组,而只执行np.log(a[a != np.inf]).sum()(您可以按布尔数组进行索引,它比基于filter 的答案更干净、更快捷。)
    • @user248237 我没有明确初始化掩码数组。 a 只是一个普通的非屏蔽数组。 ma.log 屏蔽所有未定义(实数)对数的值。然后生成的掩码数组b 被粗略地视为掩码条目不存在。
    • 我收到了AttributeError: 'SingleBlockManager' object has no attribute 'log'
    【解决方案3】:

    使用掩码数组的替代方法....

    import numpy as np
    myarray = np.array([2, 0, 1.5, -3])
    mylogarray = np.log(myarray) # The log of negative numbers is nan, 0 is -inf
    summed = mylogarray[np.isfinite(mylogarray)].sum() # isfinite will exclude inf and nan
    print(f'Sum of logged array is: {summed}')
    >>> Sum of logged array is: 1.0986122886681096
    

    【讨论】:

      【解决方案4】:

      使用filter()

      >>> array
      array([  1.,   2.,   3., -Inf])
      >>> sum(filter(lambda x: x != float('-inf'), array))
      6.0
      

      【讨论】:

      • 这是否被视为矢量化操作?有没有更有效的方法?我需要在我的代码中多次执行此操作,并且想要一种矢量化方法
      • 你是在问这是否是用迭代器就地完成的?没有。有没有更有效的方法? AFAIK,您必须遍历数组,因为没有返回迭代器的过滤器函数,除非您编写一个。
      • 我不认为过滤器代码适用于 NxM 数组。它似乎只适用于 1xM 向量。
      • filter(lambda x: x != float('-inf'), array) 的“numpythonic”方式只是 x[x != np.inf] 使用列表推导、filter 等,在 numpy 数组上比在列表上慢得多。正因为如此,numpy 数组有许多工具可以避免显式循环遍历每个元素并对其进行操作。
      【解决方案5】:

      也许你可以索引你的矩阵并使用:

      import numpy as np;
      matrix = np.array([[1.,2.,3.,np.Inf],[4.,5.,6.,np.Inf],[7.,8.,9.,np.Inf]]);
      print matrix[:,1];
      print sum(filter(lambda x: x != np.Inf,matrix[:,1]));
      print matrix[1,:];
      print sum(filter(lambda x: x != np.Inf,matrix[1,:]));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-04
        • 2023-03-26
        • 2022-01-17
        • 2011-09-04
        • 1970-01-01
        • 1970-01-01
        • 2014-02-15
        相关资源
        最近更新 更多