对'numpy.astype`

时间:2017-11-22 03:36:55

标签: python arrays numpy multidimensional-array

我对copy numpy.astype的归属感到困惑。 我查看link中的材料,它说:

By default, astype always returns a newly allocated array. If this is set to false, and the dtype, order, and subok requirements are satisfied, the input array is returned instead of a copy.

这意味着会改变ndarray对象的原始值吗? 像:

x = np.array([1, 2, 2.5])
x.astype(int, copy=False)

但似乎x仍然是原始值array([ 1. , 2. , 2.5])。 有谁能解释一下? 非常感谢~~

3 个答案:

答案 0 :(得分:3)

它们的意思是,如果原始数组完全符合您传递的指定,即具有正确的dtype,majorness并且不是子类或您设置subok标志,则将避免复制。永远不会修改输入数组。在您的示例中,dtypes不匹配,因此无论如何都会创建一个新数组。

如果您希望不复制数据,请使用视图。这将尽可能根据您的规范重新解释数据缓冲区。

x = np.array([1, 2, 2.5])
y = x.view(int)
y
#  array([4607182418800017408, 4611686018427387904, 4612811918334230528])
# y and x share the same data buffer:
y[...] = 0
x
# array([ 0.,  0.,  0.])

答案 1 :(得分:1)

  

默认情况下,astype始终返回新分配的数组。如果将其设置为false,并且满足dtype,order和subok要求,则返回输入数组而不是副本。

请注意,您引用的文档根本没有提及x被修改 - 事实上,要么返回所需类型的全新数组,要么不修改x(如果可能的话。)

在您的情况下,我认为x不符合dtype要求。文档实际上并没有真正描述这个要求(所以我可以理解你的困惑),但基本上它意味着所请求的dtype(在这种情况下为int)必须能够完全代表原始dtype的所有值(在这种情况下为float)。由于您无法在float中填写int而不会丢失某些信息,因此您无法假装xint数组。< / p>

因此,astype会返回x的新副本,每个值都会转换为int。它保留x未修改,因此要获取转换后的数组,您需要检查从astype返回的值:

x = np.array([1, 2, 2.5])
y = x.astype(int, copy=False)

print x # prints array([ 1. ,  2. ,  2.5]), since x hasn't been modified
print y # prints array([ 1. ,  2. ,  2]), since y is an integer-valued copy of x

答案 2 :(得分:1)

以下是copy=False的工作原理,返回原始数组:

In [238]: x
Out[238]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [239]: y = x.astype(int,copy=False)
In [240]: id(x)
Out[240]: 2884971680
In [241]: id(y)
Out[241]: 2884971680     # same id

In [242]: z = x.astype(int)
In [243]: id(z)
Out[243]: 2812517656     # different id

从某种意义上说,这是一个微不足道的案例;但如果其他所有情况都同样重要,我也不会感到惊讶

In [244]: w = x.astype(int,order='F',copy=False)
In [245]: id(w)
Out[245]: 2884971680   # 1d array is both order C and F

换句话说,如果需要,它会返回原始数组dtype并且order不需要任何更改。那就是如果原件已符合规格。

这与view不同。视图是一个新数组(新id)但共享数据缓冲区。相反,它更像是更简单的Python赋值y = x

我可能会改变主意,如果有人能够解决涉及copy=False更改的dtype案例。

同一个调用,但使用不同的数组将创建一个副本

In [249]: x1=np.arange(10.)      # float
In [250]: y1=x1.astype(int, copy=False)
In [251]: id(x1)
Out[251]: 2812517696
In [253]: id(y1)
Out[253]: 2812420768        # different id
In [254]: y1=x1.astype(float, copy=False)
In [255]: id(y1)
Out[255]: 2812517696

因此,如果您愿意,可以使用copy=False,例如int dtype数组,但如果数组已经int,则效率不会有任何损失。

Efficient way to cast scalars to numpy arrays

带有np.array

copy=False的行为方式大致相同 - 如果不需要转换,则返回相同的数组(id)。