2009-12-11 17 views
14

Çok verimli olmayan numpy dizilerin astype() yöntemini buluyorum. 3 milyon Uint8 noktasını içeren bir dizim var. 3x3 matrisiyle çarpmak 2 saniye sürüyor, ancak sonucu uint16'dan uint8'e çevirmek bir saniye daha sürüyor. Daha doğrusunumpy: Nasıl bir dizi türü hızlı bir şekilde dönüştürmek için

:

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() 

iççarpım ve ölçekleme 2 sn
kırpma 200 milisaniye tür dönüştürmesi 1 sn

diğer operasyonlar için gerekli süreyi göz önüne alındığında, astype beklenebilir alır götürür alır daha hızlı olmak için. Yazı tipi dönüştürme işleminin daha hızlı bir yolu var mı, yoksa bu tür dönüşümleri tahmin ederken bu kadar zor olmamalı mıyım?

Düzenleme: hedefi imgarray = imgarray.astype('B') kullandığınızda, belirtilen türe döküm dizinin bir kopyasını almak bir dosya

+0

Neden geri tekrar UInt16 gidip gerekiyor:

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

ipython en% sürümüyle gelen timeit komutu önemli bir hız bu şekilde şeyler yapıyor orada, yukarıda gösterir? Mint'in bir uint8 matrisi olması mümkün mü, o zaman dönüşüme ihtiyacınız yok. – u0b34a0f6ae

+0

, nokta ürünün sonucu uint8 aralığını aşacaktır. Aslında bir float M matrisi kullanıyordum ve tamsayıya geçmenin bana biraz iyileşme sağlayacağını düşündüm, ama bu doğru değil. – shodanex

+0

Tüm bu zaman zarfında, muhtemelen tüm bellek konumlarına erişiyor. Düzeltmek zor geliyor. –

cevap

24

son 8 bitlik dizi kurtarmaktır. Yeni tahsis edilmiş diziye işaret etmek için imgarray'ı hemen çevirdiğinizde, bu fazladan bellek ayırma gerektirir.

imgarray.view('uint8') kullanırsanız, dizinin görünümünü elde edersiniz. Bu, imgarray.dtype yerine uint8 olarak yorumlanması dışında aynı verileri kullanır. (np.dot bir uint32 dizi döndürür, böylece np.dot sonra imgarray tip uint32 taşımaktadır.)

view kullanılarak sorun, ancak, bir 32 bit tamsayı 4 8-bit tamsayı olarak görülebilir olduğu sonucu ortaya çıkar, ve Sadece son 8 bitlik değerler hakkında dikkatli olun. Bu yüzden her 8th bitlik bir tam sayıya geçmemiz gerekiyor. Biz o dilimleme ile yapabilirsiniz:

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

Bu görünümü bir dosyaya kaydedebilir miyim – shodanex

+0

@shodanex: Evet, np.save() kullanabilirsiniz. Bkz. Http://docs.scipy.org/doc/numpy-1.3.x/reference/generated/numpy.save.html – unutbu

+0

@shodanex: Diğer format seçenekleri için ayrıca bkz. Http://docs.scipy.org/doc /numpy-1.3.x/reference/routines.io.html – unutbu

İlgili konular