python numpy.where()如何工作?

paj*_*ton 90 python numpy magic-methods

我正在玩numpy和挖掘文档,我遇到了一些魔法.即我在说numpy.where():

>>> x = np.arange(9.).reshape(3, 3)
>>> np.where( x > 5 )
(array([2, 2, 2]), array([0, 1, 2]))
Run Code Online (Sandbox Code Playgroud)

他们如何在内部实现您能够将类似的东西传递x > 5给方法?我想这与某些事情有关,__gt__但我正在寻找详细的解释.

Joe*_*ton 73

他们如何在内部实现你能够将x> 5这样的东西传递给方法?

简短的回答是他们没有.

numpy数组上的任何类型的逻辑运算都返回一个布尔数组.(即__gt__,__lt__等等都返回给定条件为真的布尔数组).

例如

x = np.arange(9).reshape(3,3)
print x > 5
Run Code Online (Sandbox Code Playgroud)

收益率:

array([[False, False, False],
       [False, False, False],
       [ True,  True,  True]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

这就是为什么像是一个numpy数组if x > 5:会引发ValueError的原因x.它是一个True/False值的数组,而不是单个值.

此外,numpy数组可以通过布尔数组索引.在这种情况下,例如x[x>5]收益率[6 7 8].

老实说,你真的需要它是相当罕见的,numpy.where但它只返回布尔数组所在的指标True.通常,您可以使用简单的布尔索引来完成所需的操作.

  • 只是要指出`numpy.where`确实有2'操作模式',第一个返回`indices`,其中`condition是True`,如果存在可选参数`x`和`y`(形状与`条件`,或可播放到这样的形状!),当条件为真时它将从'x`返回值,否则从'y`返回值.因此,这使得"where"更加通用,并且可以更频繁地使用它.谢谢 (10认同)

Gar*_*erg 23

老答案 它有点令人困惑.它为您提供了您的声明属实的LOCATIONS(所有这些).

所以:

>>> a = np.arange(100)
>>> np.where(a > 30)
(array([31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
       48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
       65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
       82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
       99]),)
>>> np.where(a == 90)
(array([90]),)

a = a*40
>>> np.where(a > 1000)
(array([26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
       43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
       60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
       77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
       94, 95, 96, 97, 98, 99]),)
>>> a[25]
1000
>>> a[26]
1040
Run Code Online (Sandbox Code Playgroud)

我使用它作为list.index()的替代品,但它也有许多其他用途.我从未将它用于2D数组.

http://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html

新的答案 似乎这个人在问一些更基本的东西.

问题是你如何实现允许函数(例如where)知道所请求内容的东西.

首先请注意,调用任何比较运算符都会产生一些有趣的事情.

a > 1000
array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True`,  True,  True,  True,  True,  True,  True,  True,  True,  True], dtype=bool)`
Run Code Online (Sandbox Code Playgroud)

这是通过重载"__gt__"方法完成的.例如:

>>> class demo(object):
    def __gt__(self, item):
        print item


>>> a = demo()
>>> a > 4
4
Run Code Online (Sandbox Code Playgroud)

如您所见,"a> 4"是有效代码.

您可以在此处获取所有重载函数的完整列表和文档:http://docs.python.org/reference/datamodel.html

令人难以置信的是,这样做有多么简单.python中的所有操作都是以这种方式完成的.说a> b相当于a.gt(b)!

  • 这种比较运算符重载似乎不适用于更复杂的逻辑表达式 - 例如我不能做`np.where(a> 30和a <50)`或`np.where(30 <a <50 )`因为它最终试图评估两个布尔数组的逻辑AND,这是毫无意义的.有没有办法用`np.where`写这样的条件? (3认同)