2012-02-26 3 views
9

필자는 파이썬을 처음 사용하고 있으며 .dtype의 기능을 이해하지 못합니다. 예를 들어.dtype은 무엇을합니까?

>>> aa 
array([1, 2, 3, 4, 5, 6, 7, 8]) 
>>> aa.dtype = "float64" 
>>> aa 
array([ 4.24399158e-314, 8.48798317e-314, 1.27319747e-313, 
    1.69759663e-313]) 

난, DTYPE는 INT되어야 AA의 속성이며, I는 aa.dtype = "float64"을 할당하면 다음 단 배열 ([1.0, 2.0, 3.0, 4.0이되어야 생각 5.0, 6.0, 7.0, 8.0]).

왜 값과 크기가 변경됩니까? 무슨 뜻이에요?

는 실제로 코드 파이스 동전에서 배우는, 그리고 난 여기에 붙여 넣기한다

def to_1d(array): 
"""prepares an array into a 1d real vector""" 
    a = array.copy() # copy the array, to avoid changing global 
    orig_dtype = a.dtype 
    a.dtype = "float64" # this doubles the size of array 
    orig_shape = a.shape 
    return a.ravel(), (orig_dtype, orig_shape) #flatten and return 

내가 그것을 입력 배열의 값을 변경할 수 있지만 그 크기를 변경 야해 생각합니다. 함수가 어떻게 동작하는지 혼동한다.

+0

원하는 경우 'aa.astype (float)' –

+0

의심되는 경우 [매뉴얼 읽기] (http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#arrays-dtypes) –

+0

나는 설명서를 이해하려고 노력했지만, 영어와 컴퓨팅 언어는 나를 위해 너무 어려워서 내가 필요한 정보를 얻을 수 없었다. – user1233157

답변

33

첫째, 당신이 학습하고있는 코드가 결함이있다. 원래 작성자가 코드의 주석을 기반으로 생각한 것을 거의 확실하게 수행하지 않습니다. 저자는 아마 무엇을 의미

이 있었다 : array 항상 복잡한 숫자의 배열이 될 것입니다 경우, 그러나

def to_1d(array): 
    """prepares an array into a 1d real vector""" 
    return array.astype(np.float64).ravel() 

, 다음 원래 코드는 몇 가지 의미가 있습니다.

어레이보고는 복소 배열 (numpy.complex128) 또는 128 비트의 부동 소수점 어레이의 경우 그 크기가 두 배로 것 (a.dtype = 'float64'하는 a = a.view('float64') 일에 상당) 만 케이스. 다른 dtype의 경우에는별로 의미가 없습니다.

복잡한 경우 배열의 경우 원래 코드는 np.array([0.5+1j, 9.0+1.33j])np.array([0.5, 1.0, 9.0, 1.33])으로 변환합니다.

작성하는 청소기 방법이 그 것이다 :

def complex_to_iterleaved_real(array): 
    """prepares a complex array into an "interleaved" 1d real vector""" 
    return array.copy().view('float64').ravel() 

(나는 순간, 원래 DTYPE와 모양을 반환에 대한 부분을 무시하고 있습니다.) NumPy와에


배경 배열

여기에 무슨 일이 일어나고 있는지 설명하려면 numpy 배열이 무엇인지 조금 이해해야합니다.

numpy 배열은 "views"를 통해 배열로 해석되는 "원시"메모리 버퍼로 구성됩니다. 모든 numpy 배열을 뷰로 생각할 수 있습니다.

Views는 numpy 의미로 복사하지 않고 동일한 메모리 버퍼를 슬라이싱 및 다이 싱하는 다른 방법 일뿐입니다.

보기에는 모양, 데이터 유형 (dtype), 오프셋 및 스트라이드가 있습니다. 가능한 경우 numpy 배열에서 인덱싱/다시 형성 작업을 수행하면 원래 메모리 버퍼의 뷰가 반환됩니다.

즉, y = x.T 또는 y = x[::2]과 같은 것은 여분의 메모리를 사용하지 않으며 x 사본을 만들지 않습니다.

그래서 우리는 이와 유사한 배열이있는 경우 :

import numpy as np 
x = np.array([1,2,3,4,5,6,7,8,9,10]) 

우리는 수행하여 모양을 변경할 수를 중 하나

x = x.reshape((2, 5)) 

또는 쉽게 읽을

x.shape = (2, 5) 

, 첫 번째 옵션이 더 좋습니다. 그들은 (거의) 똑같습니다. 어느 쪽도 더 많은 메모리를 사용하게 될 복사본을 만들지 않습니다 (처음에는 새로운 파이썬 객체가 생기지 만 그 순간은 바로 옆에 있습니다).


Dtypes 및 전망

같은 일이 DTYPE에 적용됩니다. x.dtype을 설정하거나 x.view(...)을 호출하여 배열을 다른 dtype으로 볼 수 있습니다. 이 같은

그래서 우리가 할 수있는 일 :

import numpy as np 
x = np.array([1,2,3], dtype=np.int) 

print 'The original array' 
print x 

print '\n...Viewed as unsigned 8-bit integers (notice the length change!)' 
y = x.view(np.uint8) 
print y 

print '\n...Doing the same thing by setting the dtype' 
x.dtype = np.uint8 
print x 

print '\n...And we can set the dtype again and go back to the original.' 
x.dtype = np.int 
print x 

산출 :

The original array 
[1 2 3] 

...Viewed as unsigned 8-bit integers (notice the length change!) 
[1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0] 

...Doing the same thing by setting the dtype 
[1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0] 

...And we can set the dtype again and go back to the original. 
[1 2 3] 

메모리가하는 방식을이 것을 당신에게 낮은 수준의 제어를주고있다,하지만, 명심하십시오 버퍼가 해석됩니다.예를 들어

:

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)을 사용하십시오.


복소수

복소수 두 수레으로 (모두 C, Python 및 NumPy와에) 저장된다. 첫 번째 부분은 실수 부분이고 두 번째 부분은 허수 부분입니다.

그래서, 우리가 할 경우 :

import numpy as np 
x = np.array([0.5+1j, 1.0+2j, 3.0+0j]) 

우리는 진짜 (x.real)를 참조 할 수 있으며 가상 (x.imag) 부품. 이것을 float로 변환하면 허수 부 분을 버리는 것에 대한 경고를 받게되고 실제 부분 만 가진 배열을 얻게됩니다.

print x.real 
print x.astype(float) 

astype은 사본을 만들어 값을 새로운 유형으로 변환합니다.

그러나이 배열을 float으로 보는 경우 item1.real, item1.imag, item2.real, item2.imag, ... 시퀀스가 ​​표시됩니다.

print x 
print x.view(float) 

수율 :

[ 0.5+1.j 1.0+2.j 3.0+0.j] 
[ 0.5 1. 1. 2. 3. 0. ] 

각 복소수 본질적으로 두 개의 플로트, 그래서 우리 NumPy와는 기본 메모리 버퍼를 해석하는 방법을 변경하는 경우, 우리는 두 배 길이의 배열을 얻는다. 이 방법으로 DTYPE을 변경하여 조금 명확한 일을하는 데 도움이

희망 ...

+0

오그, 나는 그의 코드에 몇 시간을 보냈다. 이런! 지적 해 주셔서 고마워, 내가 dtype 부분을 제외하고, 그의 코드의 나머지는 여전히 옳은가? 고마워요, 고마워요. – user1233157

+0

배열의 _copy_를 1D 벡터로 반환하려면'array.flatten() '을 호출하면됩니다. 그러나, 내 업데이트 된 답변을 참조하십시오 ... 만약'array'가 항상 복잡한 배열이된다면, 코드는 이해가되지만 어쨌든 오해의 소지가 있습니다. –

+0

정말 고마워요! 입력 배열은 실제로 복잡한 배열입니다. 이제는 이해했습니다! 하하, 행복 – user1233157

2

dtype을 수동으로 지정하면 원하는 것보다 재 해석 캐스트가된다고 생각한다. 이것은 데이터를 하나의 것으로 변환하는 것이 아니라 직접 플로트로 해석한다고 생각합니다. 어쩌면 aa = numpy.array(aa.map(float, aa))을 시도해 볼 수 있습니다.

추가 설명 : dtype은 데이터 유형입니다. documentation

데이터 유형 객체 (numpy.dtype 클래스의 인스턴스)로부터 그대로 인용하기 가 어레이 항목에 대응하는 메모리의 크기가 고정 된 블록의 바이트를 해석하는 방법을 설명한다.

정수 및 부동 소수점에는 동일한 비트 패턴이 없으므로 int의 메모리를 볼 수없고 부동 소수점으로 볼 때 동일한 숫자가됩니다. dtype을 float64로 설정하면 실제로 정수 값을 부동 소수점 숫자로 변환하는 대신 float64로 해당 메모리를 읽도록 컴퓨터에 지시하는 것입니다.

+0

답장을 보내 주셔서 대단히 감사 드리며 배열을 1 차원 벡터로 바꾸는 작업을 수행해야하는 코드의 그림으로 배우고 있습니다. 왜 그 값을 변경했는지 혼란스러워합니다. – user1233157

+0

나는 내 질문을 업데이트하고 참조했던 코드를 붙여 넣었다. 감사합니다 :) – user1233157

1

dtype 속성의 documentationndarray에 전혀 유용하지 않습니다. 출력을 살펴보면 8 개의 4 바이트 정수 버퍼가 4 개의 8 바이트 부동 소수점으로 재 해석되는 것처럼 보일 것입니다.

은 그러나 당신이 원하는 것은 배열 생성에 dtype을 지정하는 것입니다 :

array([1, 2, 3, 4, 5, 6, 7, 8], dtype="float64") 
+0

'dtype'에 대한 문서는 다음과 같습니다 : http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#arrays-dtypes. 링크 된 문서는 dtype 클래스 문서가 아닙니다 (http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html#numpy.dtype). 문서 일뿐입니다. 다른 문서를 가리키는'ndarray.dtype'에 대한 것입니다. –

+0

내 질문이 업데이트되었습니다. 좀 살펴 보시겠습니까? 고마워. :) – user1233157

+0

글쎄, 나는 원래의 질문에 답했다. 그리고 모든 근거를 다루는 매우 포괄적 인 대답을 받아 들였다. 우리 일이 끝난 것 같아! –

5

, 당신은 메모리의 고정 블록이 해석되는 방식을 변화하고 있습니다.

예 : int8int64 내지 변경은 1 개 소자, 64 비트의 배열로, 8 소자, 8 비트 정수 배열을 변경하는 방법

>>> import numpy as np 
>>> a=np.array([1,0,0,0,0,0,0,0],dtype='int8') 
>>> a 
array([1, 0, 0, 0, 0, 0, 0, 0], dtype=int8) 
>>> a.dtype='int64' 
>>> a 
array([1]) 

참고. 그러나 동일한 8 바이트 블록입니다. 네이티브 엔디안이있는 i7 시스템에서 바이트 패턴은 int64 형식의 1과 같습니다.

변화 위치 1 :

>>> a=np.array([0,0,0,1,0,0,0,0],dtype='int8') 
>>> a.dtype='int64' 
>>> a 
array([16777216]) 

다른 예 :

>>> a=np.array([0,0,0,0,0,0,1,0],dtype='int32') 
>>> a.dtype='int64' 
>>> a 
array([0, 0, 0, 1]) 

변경 32 바이트, 32 비트 배열에 1의 총수 :

>>> a=np.array([0,0,0,1,0,0,0,0],dtype='int32') 
>>> a.dtype='int64' 
>>> a 
array([   0, 4294967296,   0,   0]) 

이것은 재 해석 된 동일한 블록 블록입니다.

+0

비록 내가 조에게 진드기를 주었지만, ur 대답은 훌륭하고 훌륭한 예입니다! 고맙습니다. – user1233157

+0

@ user1233157 : 그의 답변에 합당합니다! 당신은 여전히 ​​나에게 투표의 tho를 줄 수 있었다 :-) –

+0

그런데 멋진 대답! (+1) –