Python NumPy 数组的就地类型转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4389517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In-place type conversion of a NumPy array
提问by Sven Marnach
Given a NumPy array of int32, how do I convert it to float32in place? So basically, I would like to do
给定一个 NumPy 数组int32,如何将其转换为float32就地?所以基本上,我想做
a = a.astype(numpy.float32)
without copying the array. It is big.
无需复制数组。它很大。
The reason for doing this is that I have two algorithms for the computation of a. One of them returns an array of int32, the other returns an array of float32(and this is inherent to the two different algorithms). All further computations assume that ais an array of float32.
这样做的原因是我有两种算法来计算a. 其中一个返回 的数组int32,另一个返回 的数组float32(这是两种不同算法所固有的)。所有进一步的计算都假设a是 的数组float32。
Currently I do the conversion in a C function called via ctypes. Is there a way to do this in Python?
目前我在一个名为 via 的 C 函数中进行转换ctypes。有没有办法在 Python 中做到这一点?
采纳答案by unutbu
You can make a view with a different dtype, and then copy in-place into the view:
您可以使用不同的 dtype 创建一个视图,然后就地复制到视图中:
import numpy as np
x = np.arange(10, dtype='int32')
y = x.view('float32')
y[:] = x
print(y)
yields
产量
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32)
To show the conversion was in-place, note that copying fromxto yaltered x:
要显示转换是就地的,请注意从复制x到已y更改x:
print(x)
prints
印刷
array([ 0, 1065353216, 1073741824, 1077936128, 1082130432,
1084227584, 1086324736, 1088421888, 1090519040, 1091567616])
回答by Paul
You can change the array type without converting like this:
您可以更改数组类型而无需进行如下转换:
a.dtype = numpy.float32
but first you have to change all the integers to something that will be interpreted as the corresponding float. A very slow way to do this would be to use python's structmodule like this:
但首先您必须将所有整数更改为将被解释为相应浮点数的内容。一种非常缓慢的方法是使用 python 的struct模块,如下所示:
def toi(i):
return struct.unpack('i',struct.pack('f',float(i)))[0]
...applied to each member of your array.
...应用于数组的每个成员。
But perhaps a faster way would be to utilize numpy's ctypeslib tools (which I am unfamiliar with)
但也许更快的方法是利用 numpy 的 ctypeslib 工具(我不熟悉)
- edit -
- 编辑 -
Since ctypeslib doesnt seem to work, then I would proceed with the conversion with the typical numpy.astypemethod, but proceed in block sizes that are within your memory limits:
由于 ctypeslib 似乎不起作用,那么我将使用典型numpy.astype方法进行转换,但在内存限制内的块大小中继续:
a[0:10000] = a[0:10000].astype('float32').view('int32')
...then change the dtype when done.
...然后在完成后更改 dtype。
Here is a function that accomplishes the task for any compatible dtypes (only works for dtypes with same-sized items) and handles arbitrarily-shaped arrays with user-control over block size:
这是一个完成任何兼容 dtypes 任务的函数(仅适用于具有相同大小项目的 dtypes)并处理任意形状的数组,用户可以控制块大小:
import numpy
def astype_inplace(a, dtype, blocksize=10000):
oldtype = a.dtype
newtype = numpy.dtype(dtype)
assert oldtype.itemsize is newtype.itemsize
for idx in xrange(0, a.size, blocksize):
a.flat[idx:idx + blocksize] = \
a.flat[idx:idx + blocksize].astype(newtype).view(oldtype)
a.dtype = newtype
a = numpy.random.randint(100,size=100).reshape((10,10))
print a
astype_inplace(a, 'float32')
print a
回答by Vikas
Update: This function only avoids copy if it can, hence this is not the correct answer for this question. unutbu's answeris the right one.
更新:此功能仅在可能的情况下避免复制,因此这不是此问题的正确答案。unutbu 的答案是正确的。
a = a.astype(numpy.float32, copy=False)
numpy astype has a copy flag. Why shouldn't we use it ?
numpy astype 有一个复制标志。为什么我们不应该使用它?
回答by Ankit Barik
Use this:
用这个:
In [105]: a
Out[105]:
array([[15, 30, 88, 31, 33],
[53, 38, 54, 47, 56],
[67, 2, 74, 10, 16],
[86, 33, 15, 51, 32],
[32, 47, 76, 15, 81]], dtype=int32)
In [106]: float32(a)
Out[106]:
array([[ 15., 30., 88., 31., 33.],
[ 53., 38., 54., 47., 56.],
[ 67., 2., 74., 10., 16.],
[ 86., 33., 15., 51., 32.],
[ 32., 47., 76., 15., 81.]], dtype=float32)
回答by MIO
a = np.subtract(a, 0., dtype=np.float32)
a = np.subtract(a, 0., dtype=np.float32)
回答by u11562513
import numpy as np
arr_float = np.arange(10, dtype=np.float32)
arr_int = arr_float.view(np.float32)
use view() and parameter 'dtype' to change the array in place.
使用 view() 和参数“dtype”来更改数组。

