简体   繁体   English

理解 numpy.where

[英]Understanding numpy.where

I want to get first index of numpy array element which is greater than some specific element of that same array.我想获得 numpy 数组元素的第一个索引,它大于同一数组的某个特定元素。 I tried following:我尝试了以下操作:

>>> Q5=[[1,2,3],[4,5,6]]
>>> Q5 = np.array(Q5)
>>> Q5[0][Q5>Q5[0,0]]
array([2, 3])
>>> np.where(Q5[0]>Q5[0,0])
(array([1, 2], dtype=int32),)
>>> np.where(Q5[0]>Q5[0,0])[0][0]
1

Q1.一季度。 Is above correct way to obtain first index of an element in Q5[0] greater than Q5[0,0] ?以上是获取Q5[0]元素的第一个索引大于Q5[0,0]正确方法吗?

I am more concerned with np.where(Q5[0]>Q5[0,0]) returning tuple (array([1, 2], dtype=int32),) and hence requiring me to double index [0][0] at the end of np.where(Q5[0]>Q5[0,0])[0][0] .我更关心np.where(Q5[0]>Q5[0,0])返回元组(array([1, 2], dtype=int32),) ,因此要求我加倍索引[0][0]np.where(Q5[0]>Q5[0,0])[0][0]的末尾。

Q2. Q2。 Why this return tuple, but below returns proper numpy array?为什么这个返回元组,但下面返回正确的 numpy 数组?

>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)
array([-1,  2,  3])

So that I can index directly:这样我就可以直接索引:

>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)[1]
2

Using argmax with a boolean array will give you the index of the first True.argmax与布尔数组一起使用将为您提供第一个 True 的索引。

In [54]: q
Out[54]: 
array([[1, 2, 3],
       [4, 5, 6]])

In [55]: q > q[0,0]
Out[55]: 
array([[False,  True,  True],
       [ True,  True,  True]], dtype=bool)

argmax can take an axis/dimension argument. argmax可以采用轴/维度参数。

In [56]: np.argmax(q > q[0,0], 0)
Out[56]: array([1, 0, 0], dtype=int64)

That says the first True is index one for column zero and index zero for columns one and two.也就是说,第一个 True 是第 0 列的索引 1 和第 1 列和第 2 列的索引 0。

In [57]: np.argmax(q > q[0,0], 1)
Out[57]: array([1, 0], dtype=int64)

That says the first True is index one for row zero and index zero for row one.这表示第一个 True 是第 0 行的索引 1 和第 1 行的索引 0。


Q1.一季度。 Is above correct way to obtain first index of an element in Q5[0] greater than Q5[0,0]?以上是获取 Q5[0] 中元素的第一个索引大于 Q5[0,0] 的正确方法吗?

No I would use argmax with 1 for the axis argument then select the first item from that result.不,我会使用argmax1作为axis参数,然后从该结果中选择第一项。

Q2. Q2。 Why this return tuple为什么这个返回元组

You told it to return -1 for False values and return Q5[0] items for True values.您告诉它为 False 值返回-1为 True 值返回Q5[0]项。

Q2 ...but below returns proper numpy array? Q2 ...但下面返回正确的numpy数组?

You got lucky and chose the correct index.您很幸运并选择了正确的索引。

In [58]: A = np.arange(1,10).reshape(3,3)
In [59]: A.shape
Out[59]: (3, 3)
In [60]: A
Out[60]: 
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

np.where with just the condition is really np.nonzero . np.where只是条件真的是np.nonzero

Generate a boolean array:生成一个布尔数组:

In [63]: A==6
Out[63]: 
array([[False, False, False],
       [False, False,  True],
       [False, False, False]])

Find where that is true:找出正确的地方:

In [64]: np.nonzero(A==6)
Out[64]: (array([1]), array([2]))

The result is a tuple, one element per dimension of the condition.结果是一个元组,条件的每个维度一个元素。 Each element is an indexing array, together they define the location of the True(s)每个元素都是一个索引数组,它们一起定义了 True(s) 的位置

Another test with several True另一个测试有几个 True

In [65]: (A%3)==1
Out[65]: 
array([[ True, False, False],
       [ True, False, False],
       [ True, False, False]])
In [66]: np.nonzero((A%3)==1)
Out[66]: (array([0, 1, 2]), array([0, 0, 0]))

Using the tuple to index the original array:使用元组索引原始数组:

In [67]: A[np.nonzero((A%3)==1)]
Out[67]: array([1, 4, 7])

Using the 3 argument where to create a new array with a mix of values from A and A+10使用 3 参数where来创建一个混合了AA+10值的新数组

In [68]: np.where((A%3)==1,A+10, A)
Out[68]: 
array([[11,  2,  3],
       [14,  5,  6],
       [17,  8,  9]])

If the condition has multiple True, nonzero isn't the test tool for finding the "first", since it necessarily finds all.如果条件有多个 True,则nonzero不是查找“第一个”的测试工具,因为它必须找到所有。

The nonzero tuple can be turned into a 2d array with a transpose .可以将非零元组转换为具有transpose的二维数组。 It actually may be easier to get the "first" from this array:从这个数组中获取“第一个”实际上可能更容易:

In [73]: np.argwhere((A%3)==1)
Out[73]: 
array([[0, 0],
       [1, 0],
       [2, 0]])

You are looking in a 1d array, a row of A:您正在查找一维数组,A 行:

In [77]: A[0]>A[0,0]
Out[77]: array([False,  True,  True])
In [78]: np.nonzero(A[0]>A[0,0])
Out[78]: (array([1, 2]),)            # 1 element tuple
In [79]: np.argwhere(A[0]>A[0,0])
Out[79]: 
array([[1],
       [2]])
In [81]: np.where(A[0]>A[0,0], 100, 0)     # 3 argument where
Out[81]: array([  0, 100, 100])

So whether you are searching a 1d array or a 2d (or 3 or 4), nonzero returns a tuple with one array element per dimension.因此,无论您是搜索 1d 数组还是 2d(或 3 或 4)数组, nonzero返回每个维度有一个数组元素的元组 That way it can always be used to index a like sized array.这样它总是可以用来索引一个类似大小的数组。 The 1d tuple might look redundant, but it is consistent with other dimensional results. 1d 元组可能看起来多余,但它与其他维度结果一致。

When trying understand operations like this, read the docs carefully, and look at individual steps.在尝试理解这样的操作时,请仔细阅读文档,并查看各个步骤。 Here I look at the conditional matrix, the nonzero result, and its various uses.在这里,我看看条件矩阵、 nonzero结果及其各种用途。

numpy.where() is like a for loop with an if. numpy.where() 就像一个带有 if 的 for 循环。

numpy.where(condition, values, new_value)

condition - just like if conditions.条件- 就像 if 条件一样。
values - The values to iterate on values - 要迭代的值
new_value - if the condition is true for a value , its going to change to the new_value new_value - 如果某个条件为真,则它将更改为new_value


If we would like to write it for a 1-dimensional array it should look something like this: 如果我们想为一维数组编写它,它应该看起来像这样:
 [xv if c else yv for c, xv, yv in zip(condition, x, y)]

Example:例子:

 >>> a = np.arange(10) >>> a array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> np.where(a < 5, a, 10*a) array([ 0, 1, 2, 3, 4, 50, 60, 70, 80, 90])

First we create an array with numbers from 0 to 9 (0, 1, 2 ... 7, 8, 9)首先,我们创建一个包含 0 到 9 (0, 1, 2 ... 7, 8, 9) 数字的数组
and then we are checking for all the values in the array that are greater from 5 and multiplying their value by 10.然后我们检查数组中所有大于 5 的值并将它们的值乘以 10。
So now all the values in the array that are less then 5 stayed the same and all the values that are greater multiplied by 10所以现在数组中小于 5 的所有值保持不变,所有大于等于 10 的值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM