0

我正在对 numpy 数组中的标量值进行一些快速计算。正如文档中所说,

使用数组标量的主要优点是它们保留了数组类型(Python 可能没有可用的匹配标量类型,例如 int16)...

但是有没有比这更好(更快,更简洁)的方法来为现有数组标量分配新值:

>>> x = np.array(2.0, dtype='float32')

这可行但不是那么方便(我正在做其他算术并希望始终保留类型)。

由于明显的原因,这不起作用:

>>> x = np.array(1.0, dtype='float32')
>>> print(x, type(x))
1.0 <class 'numpy.ndarray'>
>>> x = 2.0
>>> print(x, type(x))
2.0 <class 'float'>

这也不是:

>>> x = np.array(1.0, dtype='float32')
>>> x[] = 2.0
  File "<ipython-input-319-7f36071ff81d>", line 2
    x[] = 2.0
      ^
SyntaxError: invalid syntax

也不是这个:

>>> x = np.array(1.0, dtype='float32')
>>> x[:] = 2.0
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-24-62cd4ca238ce> in <module>()
      1 x = np.array(1.0, dtype='float32')
----> 2 x[:] = 2.0

IndexError: too many indices for array

更新:

根据下面的评论(谢谢),我现在意识到我实际上并没有使用数组标量。 x是一个零维数组。

以下是创建数组标量的方法:

>>> a = np.array((1.0, 2.0, 3.0), dtype='float32')
>>> x = a[0]
>>> print(x, type(x))
1.0 <class 'numpy.float32'>

或者简单地说:

>>> x = np.float32(1.0)
>>> print(x, type(x))
1.0 <class 'numpy.float32'>
4

1 回答 1

7

可以修改 0d 数组,但array scalar不能:

In [199]: x = np.array(1.0, 'float32')
In [200]: x
Out[200]: array(1., dtype=float32)
In [201]: x.shape
Out[201]: ()
In [202]: x[...] = 2
In [203]: x
Out[203]: array(2., dtype=float32)
In [204]: x[()] =3
In [205]: x
Out[205]: array(3., dtype=float32)

您必须 mutate x,而不是为变量分配新对象。

也就是说,我不明白为什么人们想要或需要这样做。


这个 0d 数组与 不完全相同array scalar

In [207]: y = np.float32(1)
In [208]: y[...] = 2
....
TypeError: 'numpy.float32' object does not support item assignment

从具有索引的数组中提取元素会产生array scalar

In [210]: type(x[()])
Out[210]: numpy.float32

float32 对象具有许多数组属性,甚至方法,但并不完全相同:

In [211]: x.shape
Out[211]: ()
In [212]: y.shape
Out[212]: ()

可以使用与其形状大小相同的元组对数组进行索引。 arr[1,2]是一样的arr[(1,2)]。的形状x(),所以它只能用一个空元组来索引,x[()]。同样arr[:,:]适用于 2d 数组,但不适用于 1d。 ...意味着,任意数量的切片,因此适用于x[...].

__getitem__已经为类对象定义了足够多的 ,以允许像和np.generic那样进行索引。但任务尚未定义。[...][()]

np.ndarray查看、np.int_np.float32np.float和等类的类层次结构可能很有用np.int

更全面的报价

从您的链接:https ://docs.scipy.org/doc/numpy-1.13.0/user/basics.types.html#array-scalars

NumPy 通常将数组元素作为数组标量(具有关联 dtype 的标量)返回。数组标量与 Python 标量不同,但在大多数情况下,它们可以互换使用(主要例外是 v2.x 之前的 Python 版本,其中整数数组标量不能用作列表和元组的索引)。有一些例外,例如当代码需要非常特定的标量属性时,或者当它专门检查一个值是否是 Python 标量时。通常,通过使用相应的 Python 类型函数(例如,int、float、complex、str、unicode)将数组标量显式转换为 Python 标量,可以轻松解决问题。

使用数组标量的主要优点是它们保留了数组类型(Python 可能没有可用的匹配标量类型,例如 int16)。因此,使用数组标量可确保数组和标量之间的行为相同,而不管值是否在数组内。NumPy 标量也有许多与数组相同的方法。

第 2 段是在第 1 段的上下文中编写的。它试图解释为什么数组的元素是returned as array scalars. 也就是说,为什么arr[0,1]返回一个np.float32对象,而不是 Python float

这并不是建议我们array scalar直接创建一个。

我首先写了这个答案,掩盖了 0d 数组和这个引用所调用的内容之间的区别array scalars

于 2018-03-30T20:49:30.657 回答