2011-10-19 103 views
3

如果我想永久更改numpy數組的數據類型,是不是重新分配最佳方式?Numpy:永久更改使用numpy.ndarray.view?

下面是一個例子來說明語法:

import numpy as np 
x = np.array([1],dtype='float') 
x = x.view(dtype=('x','float")) 

不過,我更願意改變「到位」更改數據類型。

有什麼方法可以在原地更改數組的dtype嗎?或者是更好的如此類似的東西?:

x = x.view(dtype=('x',"float")).copy() 

回答

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的...切片返回一個視圖,以及,雖然這是一個獨立的主題。)是如此有用,是你可以做一些非常好的技巧,而無需重複記憶的東西。

例如,如果您想將浮動轉換爲整數到位(無需複製內存),則可以使用一些具有視圖的技巧來執行此操作。 (。上@ 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,而不是查看,除非需要微觀管理內存使用情況。)

+1

...實際上,我主要是想詢問如何從結構化數組轉到ndarray而不是改變表示,但是這回答了我的另一個問題。最後,即使它是相同的內存緩衝區,依賴於view(),不同的方法行爲會有所不同(例如'print','np。apply_along_axis'等)。當從x = x.view(...)開始時,你基本上改變了一些屬性而不是基礎數據,所以也許這就回答了我採用哪種約定的問題。 – hatmatrix