【问题标题】:Find the min/max excluding zeros in a numpy array (or a tuple) in python在python中查找numpy数组(或元组)中排除零的最小/最大值
【发布时间】:2011-08-23 16:33:37
【问题描述】:

我有一个数组。有效值不为零(正数或负数)。我想在数组中找到不应该考虑零的最小值和最大值。例如,如果数字只是负数。零会有问题。

【问题讨论】:

  • 您的问题是什么?你试过什么?怎么没用?

标签: python numpy


【解决方案1】:

怎么样:

import numpy as np
minval = np.min(a[np.nonzero(a)])
maxval = np.max(a[np.nonzero(a)])

a 是您的数组。

【讨论】:

  • @Shan:使用掩码数组可以避免a[np.nonzero(a)]创建的副本——看我的回答。
【解决方案2】:

如果可以选择数组中的“无效”值,最好使用nan 而不是0

>>> a = numpy.array([1.0, numpy.nan, 2.0])
>>> numpy.nanmax(a)
2.0
>>> numpy.nanmin(a)
1.0

如果这不可行,您可以使用数组掩码:

>>> a = numpy.array([1.0, 0.0, 2.0])
>>> masked_a = numpy.ma.masked_equal(a, 0.0, copy=False)
>>> masked_a.max()
2.0
>>> masked_a.min()
1.0

Josh's answer using advanced indexing相比,这样做的好处是避免创建数组的副本。

【讨论】:

  • @Sven:当我做ma.base is a 时,我得到了错误,所以它看起来不像ma 只是a 的视图,并且在某处有内存的副本。还是我测试的方式不对?
  • @JoshAdel:默认情况下,np.ma.masked_equal 会复制a。要查看视图,请使用ma = np.ma.masked_equal(a, 0.0, copy=False)
  • 这对我来说非常有效 - 我有一个案例需要检索最小/最大非零值的索引。
  • 只是旁注:我觉得将视图 (ma) 命名为与用于创建它的模块相同 (numpy.ma) 对于试图理解此代码的人来说是不必要的混淆,当它可以从字面上命名为其他更具描述性的名称。例如,为什么不a_view??
  • @Brunox13 我没有想到这会令人困惑,因为它只有三行代码,所以感谢您的反馈!我和masked_a一起去了。
【解决方案3】:

一种简单的方法是使用列表推导来排除零。

>>> tup = (0, 1, 2, 5, 2)
>>> min([x for x in tup if x !=0])
1

【讨论】:

  • 问题的标题确实说“在一个 numpy 数组(或元组)中”。
  • 在标题中没有看到元组,只阅读了数组的问题。我站纠正+1。我跳到你身上(和其他回应),因为人们发布了 numpy 问题的解决方案,将它们视为 numpy 列表,但事实并非如此。这是个人的烦恼,因为 numpy 解决方案通常效率更高。
  • 对我上面写的内容稍作更正:'....将它们视为 python 列表...'
【解决方案4】:

您可以使用生成器表达式来过滤掉零:

array = [-2, 0, -4, 0, -3, -2]
max(x for x in array if x != 0)

【讨论】:

  • 我认为 OP 是在谈论 numpy 数组而不是 python 列表。有区别,尽管您的解决方案对于后者是正确的。不会投反对票,只是让你知道。
  • 啊,刚看到数组,没看到numpy标签。
  • 这仍然适用于 numpy 数组,所以它是一个有效的答案。对于像这样的小数组,它也比 numpy 版本快得多。
【解决方案5】:

Masked arrays 通常就是专门为这些目的而设计的。您可以利用数组中的掩码零(或 ANY 其他您想要的掩码,甚至是比简单等式更复杂的掩码),并执行您在常规数组上执行的大部分操作你的蒙面数组。您还可以指定一个轴,您希望沿该轴找到最小值:

import numpy.ma as ma
mx = ma.masked_array(x, mask=x==0)
mx.min()

示例输入:

x = np.array([1.0, 0.0, 2.0])

输出:

1.0

【讨论】:

    【解决方案6】:

    这是另一种我认为更容易记住的屏蔽方式(尽管它确实复制了数组)。例如,它是这样的:

    >>> import numpy
    >>> a = numpy.array([1.0, 0.0, 2.0])
    >>> ma = a[a != 0]
    >>> ma.max()
    2.0
    >>> ma.min()
    1.0
    >>> 
    

    它可以推广到其他表达式,例如 a > 0、numpy.isnan(a)、... 您可以将掩码与标准运算符结合使用(+ 表示 OR,* 表示 AND,- 表示 NOT),例如:

    # Identify elements that are outside interpolation domain or NaN
    outside = (xi < x[0]) + (eta < y[0]) + (xi > x[-1]) + (eta > y[-1])
    outside += numpy.isnan(xi) + numpy.isnan(eta)
    inside = -outside
    xi = xi[inside]
    eta = eta[inside]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      • 2017-01-17
      • 1970-01-01
      相关资源
      最近更新 更多