[英]Numpy: strange different behavior of inplace and explicit operation
我想对 numpy 数组进行操作以使用它们的索引,并且我想包括 0 维情况。 现在我遇到了一个奇怪的情况,如果我不使用就地乘法,就会出现类型转换:
In [1]: import numpy as np
In [2]: x = 1.*np.array(1.)
In [3]: y = np.array(1.)
In [4]: y *= 1.
In [5]: x
Out[5]: 1.0
In [6]: y
Out[6]: array(1.)
In [7]: type(x)
Out[7]: numpy.float64
In [8]: type(y)
Out[8]: numpy.ndarray
为什么 x 的类型与 y 不同? 我知道,就地操作的实现方式不同,它们不会创建数组的副本,但我不明白,如果我将 0d 数组与浮点数相乘,为什么要更改类型? 它适用于一维数组:
In [1]: import numpy as np
In [2]: x = np.array(1.)
In [3]: y = np.array([1.])
In [4]: 1.*x
Out[4]: 1.0
In [5]: 1.*y
Out[5]: array([1.])
In [7]: type(1.*x)
Out[7]: numpy.float64
In [8]: type(1.*y)
Out[8]: numpy.ndarray
我认为,这很奇怪......现在我遇到了以下问题,我必须单独处理 0d-array :
In [1]: import numpy as np
In [2]: x = np.array(1.)
In [3]: y = np.array(1.)*1.
In [4]: x[x>0]
Out[4]: array([1.])
In [5]: y[y>0]
Out[5]: array([1.])
In [6]: x[x>0] = 2.
In [7]: y[y>0] = 2.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-5f9c5b138fc0> in <module>()
----> 1 y[y>0] = 2.
TypeError: 'numpy.float64' object does not support item assignment
最终,这种行为归结为开发人员做出的自由选择,因此不一定存在良好的解释。 但是,我想捍卫/解释观察到的行为如下。
如果是
y = np.array(1.)
y *= 1.
我们创建了一个np.ndarray
对象y
,然后执行它的操作。 在这里,最自然的行为是操作(可能)改变y
的值,而类型应该保持不变。 这确实是实际发生的事情。
顺便说一句,请注意type和 NumPy 数据类型(或dtype )之间的区别。 如果我们开始了与y = np.array(1)
(D类的np.int64
),操作y *= 1.
是现在,因为这将非法需要改变dtype
就地!
对于x = 1.*np.array(1.)
,让我们把它白化为
x1 = 1.
x2 = np.array(1.)
x = x1*x2
在这里,我们不创建一个对象,然后对其进行操作。 相反,我们创建了两个对象x1
和x2
,然后使用对称运算(这里是二进制乘法)将它们组合成第三个对象x
。 由于x1
和x2
碰巧具有不同(但兼容)的类型,因此x
的类型并不明显:它同样可以是x1
的类型( float
)或x2
的类型( numpy.ndarray
)。 令人惊讶的是,实际答案都不是,因为x
的类型是np.float64
。 这种行为源于两个不同的选择。
将 0 维数组与标量组合会生成标量,而不是 0 维数组。 这真的是让你绊倒的选择。 我想它也可能被反过来选择了。 全局开关(例如np.return_scalar = False
)将是一个不错的功能!
将 NumPy 数值数据类型与标准 Python 数值类型相结合会产生 NumPy 数值数据类型。 在这里,第一类包括np.int64
、 np.float64
、 np.complex128
(以及更多),而后者仅包含int
、 float
和complex
(对于Python 2,也是long
)。 因此, float
时间np.float64
导致np.float64
。
综合起来,这两个选择确实使x = 1.*np.array(1.)
成为np.float64
的 NumPy 标量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.