2009-12-11 67 views
14

我發現numpy數組的astype()方法效率不高。我有一個包含 300萬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要更快。 有沒有更快的方法來做類型轉換,或者當我猜測類型轉換不應該那麼困難時我錯了嗎?

編輯:我們的目標是最終的8位陣列保存到一個文件

+0

爲什麼你需要去UINT16和回來?是否可以將'M'作爲uint8矩陣,那麼你不需要轉換。 – u0b34a0f6ae 2009-12-11 15:49:53

+0

點積的結果將超出uint8範圍。我最初使用的是浮點M矩陣,並認爲去整數會給我一些改進,但事實並非如此。 – shodanex 2009-12-11 16:02:48

+0

什麼需要所有的時間,可能是訪問所有的內存位置。聽起來很難解決。 – 2009-12-11 16:22:55

回答

24

當您使用imgarray = imgarray.astype('B'),你得到的數組的一個拷貝,轉換爲指定的類型。這需要額外的內存分配,即使您立即將imgarray指向新分配的數組。如果你使用imgarray.view('uint8'),那麼你會看到數組。這使用相同的數據,但它被解釋爲uint8而不是imgarray.dtype。 (np.dot返回uint32陣列,所以np.dot後,imgarrayuint32類型。)

使用view的問題,但是,是一個32位整數變成如圖4 8位整數觀看,並且我們只關心最後8位的值。所以我們需要跳到每4個8位整數。我們可以做到這一點與切片:

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

IPython中的%timeit命令顯示有一個顯著加快做的事情是這樣的:

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 2009-12-11 17:42:21

+0

@shodanex:是的,您可以使用np.save()。請參閱http://docs.scipy.org/doc/numpy-1.3.x/reference/generated/numpy.save.html – unutbu 2009-12-11 18:08:40

+0

@shodanex:有關其他格式選項,另請參閱http://docs.scipy.org/doc /numpy-1.3.x/reference/routines.io.html – unutbu 2009-12-11 18:09:20