2011-10-19 16 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は本当に、ありませんことをお勧めします。

ナンシーアレイは、基本的にメモリバッファを表示する単なる方法です。

Viewsは、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... 

だから、私たちはこのような場合には、基礎となるビット浮動小数点数として元のメモリバッファのを解釈しています。

intをfloatとしてリキャストして新しいコピーを作成する場合は、x.astype(np.float)を使用します。

ビュー(dtypes ...のスライスは別のトピックですが、スライスも同様です)は非常に便利です。メモリ内のものを複製することなく、本当に素敵なトリックを行うことができます。

たとえば浮動小数点数を(メモリを複製せずに)のintに変換したい場合は、ビューを使用してこれを行うことができます。 (。@の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は、「入力」と「出力」のdtypeにかかわらず常にコピーを作成します。 viewを参照すると、実際に人々が実際に望むものです。 (例えば、intとfloatの間で変換したい場合は、メモリ使用量を微調整する必要がない限り、ビューではなくastypeを使用してください)。

+1

...実際には、構造化配列からndarray表現を変えるのではなく、私が持っていた別の質問に答えます。結局、同じメモリバッファであっても、 'view()'によっては、異なるメソッドが異なる振る舞いをします( 'print'、' np。apply_along_axis'など)。 'x = x.view(...) 'から行くときには基本的にいくつかの属性を変更しますが、基礎となるデータは変更しません。 – hatmatrix

関連する問題