2009-12-11 6 views
14

numpy 배열의 astype() 메서드는 그리 효율적이지 않습니다. 나는 3 백만 Uint8 포인트를 포함하는 배열을 가지고 있습니다. 3x3 행렬로 곱하면 2 초가 걸리지 만 uint16의 결과를 uint8로 변환하는 데는 또 다른 시간이 걸립니다. 더 정확하게numpy : 배열 형식을 빠르게 변환하는 방법

:

print time.clock() 
    imgarray = np.dot(imgarray, M)/255 
    print time.clock() 
    imgarray = imgarray.clip(0, 255) 
    print time.clock() 
    imgarray = imgarray.astype('B') 
    print time.clock() 

내적 및 스케일링은 2 초
클리핑이 200 밀리 초 타입 변환이 1 초

다른 작업에 걸리는 시간을 감안할 때, 내가 astype를 기대한다 소요됩니다 더 빠르다. 형식 변환을 더 빨리 수행 할 수 있습니까? 아니면 형식 변환이 어렵지 않을 때 잘못 생각합니까?

편집 : 목표는 당신이 imgarray = imgarray.astype('B')을 사용하면 지정된 형식으로 캐스팅 배열의 카피를 얻을 파일

+0

가 왜 다시 UINT16로 이동해야하나요 :

imgarray.view('uint8')[:,::4]

IPython의 %의 timeit 명령은 상당한 속도가 이런 식으로 일을 거기 보여줍니다? uint8 행렬로 'M'을 사용할 수 있습니까? 그렇다면 변환이 필요하지 않습니다. – u0b34a0f6ae

+0

내적 결과가 uint8 범위를 초과합니다. 원래 float M 행렬을 사용하고 있었고 정수로가는 것이 나에게 약간의 개선점을 줄 것이라고 생각했지만 이것이 사실이 아닙니다. – shodanex

+0

아마도 그 시간이 모두 걸리면 모든 메모리 위치에 액세스하고있는 것입니다. 고치는 소리가 힘듭니다. –

답변

24

에 마지막 8 비트 배열을 저장하는 것입니다. 새로 할당 된 배열을 가리 키도록 imgarray를 즉시 뒤집더라도이 작업에는 추가 메모리 할당이 필요합니다.

imgarray.view('uint8')을 사용하면 배열을 볼 수 있습니다. 이 데이터는 imgarray.dtype 대신 uint8으로 해석된다는 점을 제외하면 동일한 데이터를 사용합니다. (np.dotuint32 배열을 반환하므로 np.dotimgarray 유형 uint32이다.)

view을 사용하는 데 문제가 있지만, 32 비트 정수 4 내지 8 비트 정수로 간주가되도록하고, 우리 마지막 8 비트의 값만주의하십시오. 따라서 우리는 매 4 번째 8 비트 정수로 건너 뛸 필요가 있습니다. 우리는 슬라이스로 할 수있는 :

In [37]: %timeit imgarray2 = imgarray.astype('B') 
10000 loops, best of 3: 107 us per loop 

In [39]: %timeit imgarray3 = imgarray.view('B')[:,::4] 
100000 loops, best of 3: 3.64 us per loop 
+1

이 뷰를 파일로 저장할 수 있습니까 – shodanex

+0

@shodanex : 예, np.save()를 사용할 수 있습니다. http://docs.scipy.org/doc/numpy-1.3.x/reference/generated/numpy.save.html – unutbu

+0

@ shodanex를 참조하십시오. 다른 형식 옵션은 http://docs.scipy.org/doc를 참조하십시오. /numpy-1.3.x/reference/routines.io.html – unutbu

관련 문제