SORU
23 Kasım 2010, Salı


NumPy 2 boyutlu bir dizinin Dilimleme, ya da nasıl nxn bir dizi (n>m) ayrışık ekran kartı bir submatrix özü?

Bir NumPy nxn dizi dilim istiyorum. Bir ayıklamak istiyorumkeyfim satır ve bir dizi sütun seçimi (satır/sütun numaraları olmadan herhangi bir desen gibi), yeni, ayrışık ekran kartı bir dizi yapmak. Bu örnek için dizi 4x4 ve 2x2 bir dizi ayıklamak istiyorum diyelim.

İşte bizim dizi:

from numpy import *
x = range(16)
x = reshape(x,(4,4))

print x
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]

Kaldırmak için satır ve sütunların aynı. En kolay dava başında olan 2x2 bir submatrix özü istediğimde veya sonunda, yani :

In [33]: x[0:2,0:2]
Out[33]: 
array([[0, 1],
       [4, 5]])

In [34]: x[2:,2:]
Out[34]: 
array([[10, 11],
       [14, 15]])

Ama eğer satır başka bir karışım kaldırmak için gerekiyorsa/sütun ne? Eğer birinci ve üçüncü satır/satırları kaldırmak için gerekiyorsa, böylece 10* *submatrix ne ayıklanıyor? Satır/satırları herhangi bir bileşimi olabilir. Ben sadece iki satır ve sütunların endeksleri benim diziler/lists dizini kullanarak gereken bir yerde okumuştum, ama çalışmak için görünmüyor:

In [35]: x[[1,3],[1,3]]
Out[35]: array([ 5, 15])

Bir yol buldum:

    In [61]: x[[1,3]][:,[1,3]]
Out[61]: 
array([[ 5,  7],
       [13, 15]])

Bunu kabul edebilirim, ancak pek okunabilir, bu ilk sorun. Eğer birisi daha iyi bir çözüm varsa, kesinlikle duymak isterim.

Şey ben dizileri ile dizin oluşturma diziler NumPy istenen dizinin bir kopyasını yapmak için zorlar on a forum okumak, böylece büyük diziler ile tedavi ederken bu bir sorun haline gelebilir. Neden / nasıl bu mekanizma çalışıyor mu?

CEVAP
23 Kasım 2010, Salı


Bu soruyu cevaplamak için, çok boyutlu bir dizi Numpy nasıl çalıştığını bakmak zorundayız. Hadi ilk soru dizi x. Tampon x atanan 16 15 0 tamsayıları artan içerir. Eğer bir element, erişim, derseniz x[i,j], NumPy bu elemanın bellek konumu buffer başına göre anlamaya vardır. Bu etkisi i*x.shape[1] j (ve gerçek bir bellek ofset almak için bir int boyutu ile çarpılarak) hesaplanarak yapılır.

Temel bir alt-dize ayıklamak y = x[0:2,0:2], sonuç nesnesi gibi Dilimleme x ile temel arabellek paylaşacak. Ama eğer y[i,j] ücretli olursa ne olur? NumPy verileri y ait bellekte ardışık olduğu için i*y.shape[1] j dizi ofset hesaplamak için kullanabilirsiniz.

NumPy getirerek bu sorunu çözeradımlar. Bellek gerçekten hesaplanır ne x[i,j], erişme uzaklığı hesaplarken i*x.strides[0] j*x.strides[1] (ve bu zaten bir int boyutu için faktör vardır:

x.strides
(16, 4)

y gibi yukarıda çıkartıldığında, NumPy yeni bir tampon, ama onu oluşturmazyokyeni dizi bir nesne aynı tampon (aksi y sadece*.* 27 eşit olacaktır) başvuru oluşturun Yeni bir dizi nesnesi olacak bir farklı şekli x ve belki de farklı bir başlangıç uzaklığı içine tampon, ama paylaşacak adımlar ile x (bu durumda en az):

y.shape
(2,2)
y.strides
(16, 4)

Bu şekilde, bellek y[i,j] uzaklık hesaplama doğru sonucu verecektir.

Ama NumPy z=x[[1,3]] gibi bir şey için ne yapmalıyım? Adımlar mekanizması eğer orijinal tampon z için kullanılırsa doğru dizin oluşturma izin vermez. NumPy teorik olarakolabiliradımlar daha karmaşık bir mekanizma eklemek, ama bu element erişim nispeten pahalı, bir şekilde bir dizi fikrine meydan olur. Buna ek olarak, bir görünüm gerçekten basit bir nesne olmaz.

Bu the NumPy documentation on indexing derinlemesine kaplıdır.

Oh, ve neredeyse gerçek soruyu unuttum: beklendiği gibi birden fazla liste ile dizin oluşturma çalışmasını sağlamak için Burada

x[[[1],[3]],[1,3]]

Bu dizin dizi ortak bir şekil için broadcasted olmasıdır. Bu belirli bir örnek için de, temel Dilimleme ile bunu yapabilirsiniz:

x[1::2, 1::2]

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • LiveForGodsKingdom

    LiveForGodsK

    6 NİSAN 2008
  • The Computer Chronicles

    The Computer

    7 Kasım 2012
  • UCBerkeley

    UCBerkeley

    3 Mayıs 2006