python numpy.where()如何工作?

我正在玩x > 5并通过文档挖掘,我遇到了一些魔法。 即我说的是__gt__

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

他们如何在内部实现您能够将x > 5之类的内容传递给方法? 我想这与__gt__有关,但我正在寻找详细的解释。

pajton asked 2019-09-11T02:38:36Z
3个解决方案
72 votes

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

简短的回答是他们没有。

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

例如。

x = np.arange(9).reshape(3,3)
print x > 5

收益率:

array([[False, False, False],
       [False, False, False],
       [ True,  True,  True]], dtype=bool)

如果True是一个numpy数组,这就像numpy.where之类的东西引发ValueError的原因相同。 它是一个True / False值的数组,而不是单个值。

此外,numpy数组可以通过布尔数组索引。 例如。 在这种情况下,numpy.whereTrue

老实说,你真的需要numpy.where是相当罕见的,但它只返回布尔数组为True的指标。通常你可以用简单的布尔索引做你需要的。

Joe Kington answered 2019-09-11T02:39:39Z
23 votes

老答案这有点令人困惑。 它为您提供了您的声明属实的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

我使用它作为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)`

这是通过重载“__gt__”方法完成的。 例如:

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


>>> a = demo()
>>> a > 4
4

如您所见,“a> 4”是有效代码。

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

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

Garrett Berg answered 2019-09-11T02:41:08Z
0 votes

np.where返回一个长度等于调用它的numpy ndarray的维度的元组(换句话说ndim),元组的每个项目都是初始ndarray中条件为True的所有值的索引的numpy ndarray。 (请不要将尺寸与形状混淆)

例如:

x=np.arange(9).reshape(3,3)
print(x)
array([[0, 1, 2],
      [3, 4, 5],
      [6, 7, 8]])
y = np.where(x>4)
print(y)
array([1, 2, 2, 2], dtype=int64), array([2, 0, 1, 2], dtype=int64))


y是长度为2的元组,因为np.where是2.元组中的第1项包含大于4的所有元素的行号,第2项包含大于4的所有项的列号。如您所见,[1,2, 2,2]对应于行号5,6,7,8,[2,0,1,2]对应于列号5,6,7,8请注意,ndarray沿第一维(行方向)遍历。

同样的,

x=np.arange(27).reshape(3,3,3)
np.where(x>4)


将返回长度为3的元组,因为x有3个维度。

但等等,还有更多到np.where!

当两个额外的参数被添加到np.where; 它将对由上述元组获得的所有成对行列组合进行替换操作。

x=np.arange(9).reshape(3,3)
y = np.where(x>4, 1, 0)
print(y)
array([[0, 0, 0],
   [0, 0, 1],
   [1, 1, 1]])
Piyush Singh answered 2019-09-11T02:42:09Z
translate from https://stackoverflow.com:/questions/5642457/how-does-python-numpy-where-work