如果我想永久更改numpy数组的数据类型,那么重新分配是最好的方法吗?
以下是一个说明语法的示例:
import numpy as np
x = np.array([1],dtype='float')
x = x.view(dtype=('x','float"))
但是,我更愿意更改“就地”更改数据类型。
有没有办法在适当的位置更改数组的dtype?或者这样的事情会更好吗?:
x = x.view(dtype=('x',"float")).copy()
答案 0 :(得分:5)
真的没有“永久”的dtype。
Numpy数组基本上只是一种查看内存缓冲区的方法。
在numpy意义上,视图只是一种切片和切割相同内存缓冲区而不进行复制的不同方式。
但请记住,这可以让您对内存缓冲区的解释方式进行低级控制。
例如:
import numpy as np
x = np.arange(10, dtype=np.int)
print 'An integer array:', x
print 'But if we view it as a float:', x.view(np.float)
print "...It's probably not what we expected..."
这会产生:
An integer array: [0 1 2 3 4 5 6 7 8 9]
But if we view it as a float: [ 0.00000000e+000 4.94065646e-324
9.88131292e-324 1.48219694e-323 1.97626258e-323
2.47032823e-323 2.96439388e-323 3.45845952e-323
3.95252517e-323 4.44659081e-323]
...It's probably not what we expected...
因此,在这种情况下,我们将原始内存缓冲区的底层位解释为浮点数。
如果我们想要使用重新设置为浮动的整数制作新副本,我们将使用x.astype(np.float)
。
视图的原因(dtypes ...切片也返回一个视图,虽然这是一个单独的主题。)是如此有用,是你可以做一些非常好的技巧而不必复制内存中的东西。
例如,如果您想将浮点数转换为ints 到位(不重复内存),您可以使用一些带有视图的技巧来执行此操作。 (根据@ unutbu的回答on this question。)
import numpy as np
x = np.arange(10, dtype=np.int)
print 'The original int array:', x
# We would have just used y = x.astype(np.float), but it makes a copy.
# This doesn't. If we're worried about memory consumption, it's handy!
y = x.view(np.float)
y[:] = x
print 'The new float array:', y
print 'But, the old int array has been modified in-place'
print x
print "They're both views into the same memory buffer!"
同样,你可以做各种低级别的比特:
import numpy as np
x = np.arange(10, dtype=np.uint16)
y = x.view(np.uint8)
print 'The original array:', x
print '...Viewed as uint8:', y
print '...Which we can do some tricks with', y[::2]
# Now let's interpret the uint16's as two streams of uint8's...
a, b = y[::2], y[1::2]
b[:] = np.arange(10, dtype=np.uint8)
print a
print b
print x
print y
# Notice that the original is modified... We're not duplicating memory anywhere!
要回答你的问题,“更好”是相对的。您想要一个副本,还是想以不同的方式查看相同的内存缓冲区?
作为旁注,astype
始终复制,无论“输入”和“输出”dtypes如何。这通常是人们在提到view
时真正想要的。 (例如,如果要在整数和浮点数之间进行转换,请使用astype
,而不是查看,除非您需要微观管理内存使用情况。)