当前位置: 首页 > 面试题库 >

numpy.where(condition)的输出不是数组,而是数组的元组:为什么?

芮学
2023-03-14
问题内容

我正在尝试该numpy.where(condition[, x, y])功能。
从numpy文档中,我了解到,如果仅给出一个数组作为输入,它应该返回该数组非零的索引(即“
True”):

如果仅给出条件,则返回元组condition.nonzero(),其中condition为True的索引。

但是,如果尝试一下,它将返回一个包含两个元素的 元组 ,其中第一个是所需的索引列表,第二个是空元素:

>>> import numpy as np
>>> array = np.array([1,2,3,4,5,6,7,8,9])
>>> np.where(array>4)
(array([4, 5, 6, 7, 8]),) # notice the comma before the last parenthesis

所以问题是:为什么?这种行为的目的是什么?在什么情况下这很有用?确实,要获得所需的索引列表,我必须添加索引,如中所示np.where(array>4)[0],这似乎是“丑陋的”。

附录

我从一些答案中了解到,它实际上只是一个元素的元组。仍然我不明白为什么要这样输出。为了说明这是不理想的,请考虑以下错误(首先引起了我的问题):

>>> import numpy as np
>>> array = np.array([1,2,3,4,5,6,7,8,9])
>>> pippo = np.where(array>4)
>>> pippo + 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "int") to tuple

因此您需要做一些索引来访问实际的索引数组:

>>> pippo[0] + 1
array([5, 6, 7, 8, 9])

问题答案:

在Python中(1)意味着1()可以自由添加到组号和表达式中以提高可读性(例如(1+3)*3v
(1+3,)*3)。因此,要表示它使用的1元素元组(1,)(并要求您也使用它)。

从而

(array([4, 5, 6, 7, 8]),)

是一个元素元组,该元素是一个数组。

如果应用where到2d数组,结果将是2元素元组。

结果where是可以将其直接插入分度槽,例如

a[where(a>0)]
a[a>0]

应该返回相同的东西

就像

I,J = where(a>0)   # a is 2d
a[I,J]
a[(I,J)]

或举个例子:

In [278]: a=np.array([1,2,3,4,5,6,7,8,9])
In [279]: np.where(a>4)
Out[279]: (array([4, 5, 6, 7, 8], dtype=int32),)  # tuple

In [280]: a[np.where(a>4)]
Out[280]: array([5, 6, 7, 8, 9])

In [281]: I=np.where(a>4)
In [282]: I
Out[282]: (array([4, 5, 6, 7, 8], dtype=int32),)
In [283]: a[I]
Out[283]: array([5, 6, 7, 8, 9])

In [286]: i, = np.where(a>4)   # note the , on LHS
In [287]: i
Out[287]: array([4, 5, 6, 7, 8], dtype=int32)  # not tuple
In [288]: a[i]
Out[288]: array([5, 6, 7, 8, 9])
In [289]: a[(i,)]
Out[289]: array([5, 6, 7, 8, 9])

======================

np.flatnonzero 展示了仅返回一个数组的正确方法,而不管输入数组的尺寸如何。

In [299]: np.flatnonzero(a>4)
Out[299]: array([4, 5, 6, 7, 8], dtype=int32)
In [300]: np.flatnonzero(a>4)+10
Out[300]: array([14, 15, 16, 17, 18], dtype=int32)

它的文档说:

这等效于a.ravel()。nonzero()[0]

实际上,这实际上就是函数的功能。

通过展平a消除了如何处理多个尺寸的问题。然后,它将响应从元组中删除,从而为您提供一个简单的数组。通过展平,它对于一维数组并没有特殊情况。

==========================

@Divakar建议np.argwhere

In [303]: np.argwhere(a>4)
Out[303]: 
array([[4],
       [5],
       [6],
       [7],
       [8]], dtype=int32)

哪个 np.transpose(np.where(a>4))

或者,如果您不喜欢列向量,则可以再次转置它

In [307]: np.argwhere(a>4).T
Out[307]: array([[4, 5, 6, 7, 8]], dtype=int32)

除了现在是一个1xn数组。

我们也可以包裹wherearray

In [311]: np.array(np.where(a>4))
Out[311]: array([[4, 5, 6, 7, 8]], dtype=int32)

大量的以阵列出来的方式where元组([0]i,=transposearray,等等)。



 类似资料:
  • 问题内容: 我的运行方式如下: 哪里是这个要点。 当我查看结果时,它是一个1D数组而不是2D数组: 它似乎是一个元组数组: 如果我从调用中删除转换器规范,它将正常工作并生成2D数组: 问题答案: 返回的结果称为 结构化ndarray ,例如,请参见此处:http : **//docs.scipy.org/doc/numpy/user/basics.rec.html** 。这是因为您的数据不是同质的

  • 从Joshua Bloch的Effective Java中, > 数组与泛型类型有两个重要的区别。第一个数组是协变的。泛型是不变的。 协变简单地说,如果X是Y的子型,那么X[]也将是Y[]的子型。数组是协变的,因为字符串是对象的子类型,所以 不变简单地说,不管X是不是Y的子类型, 我的问题是为什么决定在Java中使数组是协变的?还有其他的SO帖子,比如为什么数组是不变的,但是列表是协变的?,但它们

  • 问题内容: 从两个列表中选择列表的最快,最优雅的方法是什么? 我有 我想要 我当时在考虑使用map而不是zip,但我不知道是否有一些标准库方法作为第一个参数。 我可以为此定义自己的功能,并使用map,我的问题是是否已经实现了某些功能。 否 也是答案。 问题答案: 如果您要压缩2个以上的列表(就此而言,甚至压缩2个),一种可读的方式将是: 这使用列表推导并将列表(元组)中的每个元素转换为列表。

  • 问题内容: 摘自Joshua Bloch的Effective Java, 数组在两个重要方面不同于通用类型。第一数组是协变的。泛型是不变的。 协变量仅表示如果X是Y的子类型,则X []也将是Y []的子类型。数组是协变的,因为字符串是Object的子类型,所以 不变式仅表示X是否为Y的子类型, 问题答案: Java和C#的早期版本不包含泛型(又称参数多态性)。 在这种情况下,使数组不变会排除有用的

  • 问题内容: 我正在尝试检查数组数组是否包含字符串数组。我的错误消息说: “无法为’contains’找到重载,该重载接受类型为’([([[((String)])]),[(String)])类型的参数列表 这是怎么回事!? 问题答案: 不符合协议,因此 不能在这里使用。您可以使用基于谓词的变体 代替: 因为是为元素数组定义的。

  • 我必须编写一个名为productOfPrevious的方法,它接受一个整数数组,并返回一个与输入大小相同的整数数组。返回数组中的每个单元格都是该单元格与前面所有单元格的乘积。 这是我的密码。但我不知道为什么输出数组中的元素总是为零。 输入:{1,2,3,4,5} 我需要的输出:{1,2,6,24,120} 我获得的输出:{0,0,0,0,0} 我的代码有什么问题吗?