有没有更好的方法为numpy数组标量赋值?

时间:2018-03-30 20:45:03

标签: python arrays numpy scalar copy-assignment

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

  

使用数组标量的主要优点是它们可以保留数据标量   数组类型(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'>

1 个答案:

答案 0 :(得分:3)

可以修改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[:,:]适用于2d数组,但不适用于1d。 ...表示任意数量的切片,因此适用于x[...]

已为__getitem__类对象定义了足够的np.generic,以允许对[...][()]进行索引。但是这项任务尚未确定。

查看类np.ndarraynp.int_np.float32np.floatnp.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