gre*_*een 7 python arrays numpy in-place numpy-ndarray
我想操作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
Run Code Online (Sandbox Code Playgroud)
为什么x的类型与y不同?我知道,inplace操作是不同的实现,他们不创建数组的副本,但我不明白,为什么类型被更改,如果我将一个0d数组与浮点数相乘?它适用于1d阵列:
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
Run Code Online (Sandbox Code Playgroud)
我想,这很奇怪......现在我遇到了以下问题,我必须分别处理0d数组:
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
Run Code Online (Sandbox Code Playgroud)
最终,这种行为归结为开发人员做出的自由选择,因此不一定存在好的解释。然而,我想对观察到的行为进行如下辩护/解释。
如果是
y = np.array(1.)
y *= 1.
Run Code Online (Sandbox Code Playgroud)
我们创建一个np.ndarray对象y,然后对其进行操作。在这里,最自然的行为是操作(可能)改变的值y,而类型应保持不变。这确实是实际发生的情况。
另外,请注意type和 NumPy 数据类型(或dtype)之间的区别。y = np.array(1)如果我们从(dtype of )开始np.int64,该操作y *= 1.现在是非法的,因为这需要dtype就地更改!
对于这种情况x = 1.*np.array(1.),让我们将其白化为
x1 = 1.
x2 = np.array(1.)
x = x1*x2
Run Code Online (Sandbox Code Playgroud)
在这里,我们不创建一个对象然后对其进行操作。相反,我们创建两个对象x1和x2,然后x使用对称运算(此处为二进制乘法)将它们组合成第三个对象 。由于x1和x2恰好具有不同(但兼容)的类型,因此 的类型x是非显而易见的:它同样可以是x1( ) 的类型或( )float的类型。令人惊讶的是,实际答案都不是,因为 的类型是。这种行为源于两个不同的选择。x2numpy.ndarrayxnp.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.)dtype 的 NumPy 标量np.float64。