有没有更好的方法为 numpy 数组标量分配新值?

Is there a better way to assign a new value to a numpy array scalar?

我正在对 numpy 数组中的标量值进行一些快速计算。正如 documentation

中所说

The primary advantage of using array scalars is that they preserve the array type (Python may not have a matching scalar type available, e.g. 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'>

可以修改 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)

您必须改变 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[:,:] 适用于二维数组,但不适用于一维数组。 ... 表示任意数量的切片,因此适用于 x[...].

已经为 np.generic class 对象定义了足够的 __getitem__ 以允许像 [...][()] 这样的索引。但是赋值还没有定义。

查看 class 的 class 层次结构可能会有用,例如 np.ndarraynp.int_np.float32np.float , 和 np.int.

更完整的引用

来自你的link:https://docs.scipy.org/doc/numpy-1.13.0/user/basics.types.html#array-scalars

NumPy generally returns elements of arrays as array scalars (a scalar with an associated dtype). Array scalars differ from Python scalars, but for the most part they can be used interchangeably (the primary exception is for versions of Python older than v2.x, where integer array scalars cannot act as indices for lists and tuples). There are some exceptions, such as when code requires very specific attributes of a scalar or when it checks specifically whether a value is a Python scalar. Generally, problems are easily fixed by explicitly converting array scalars to Python scalars, using the corresponding Python type function (e.g., int, float, complex, str, unicode).

The primary advantage of using array scalars is that they preserve the array type (Python may not have a matching scalar type available, e.g. int16). Therefore, the use of array scalars ensures identical behaviour between arrays and scalars, irrespective of whether the value is inside an array or not. NumPy scalars also have many of the same methods arrays do.

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

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

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