我对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])
。
有谁能解释一下?
非常感谢~~
答案 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
而不会丢失某些信息,因此您无法假装x
是int
数组。< / 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)。