Uyuşmuş bir diziyi izlemek mi?


90

2D numpydizim var. İlk ksatırları ve tüm sütunları içeren bir görünüm oluşturmanın bir yolu var mı ?

Önemli olan, temeldeki verileri kopyalamaktan kaçınmaktır (dizi o kadar büyüktür ki, kısmi kopyalar yapmak mümkün değildir.)

Yanıtlar:


228

Elbette, normalde yaptığınız gibi dizine ekleyin. Örneğin y = x[:k, :] bu orijinal diziye bir görünüm dönecektir. Hiçbir veri kopyalanmayacak ve üzerinde yapılan herhangi bir güncelleme yyansıtılacaktır xve bunun tersi de geçerlidir.


Düzenle:

Genellikle uint8'lerin> 10GB 3B dizileriyle çalışırım, bu yüzden bu konuda çok endişeleniyorum ... Aklınızda birkaç şey varsa, Numpy bellek yönetiminde çok verimli olabilir. Bellekteki dizilerin kopyalarını yapmaktan kaçınmak için birkaç ipucu:

Kullanım +=, -=, *=vb dizinin bir kopyasını yapmaktan kaçınmaya. Örneğin x += 10, diziyi yerinde değiştirirken, x = x + 10bir kopya oluşturup onu değiştirir. (ayrıca numexpr'a bir göz atın )

Eğer bir kopyasını yapmak istiyorum yoksa x = x + 10, farkında x = x + 10.0neden olacaktır xotomatik olarak zaten değilse, bir kayan noktalı diziye yukarı başına gitti. Bununla birlikte, x += 10.0, burada xbir tam sayı dizisi olan, neden olur 10.0, bunun yerine olmak dizisi ile aynı hassas bir int aşağı döküm.

Ek olarak, birçok numpy işlevi bir outparametre alır, böylece yerinde np.abs(x, x)değerin mutlak değerini almak gibi şeyler yapabilirsiniz x.


İkinci bir düzenleme olarak, aşağıda uyuşmuş dizilere sahip kopyalara karşı görünümler hakkında birkaç ipucu daha :

Python listelerinden farklı olarak, y = x[:]bir kopya döndürmez, bir görünüm döndürür. Bir kopya istiyorsanız (bu tabii ki kullandığınız bellek miktarını iki katına çıkarır) kullanıny = x.copy()

Sık sık uyuşmuş dizilerin "süslü indekslemesini" duyarsınız. Bir listeyi (veya tamsayı dizisini) indeks olarak kullanmak "süslü indekslemedir". Çok faydalı olabilir, ancak verileri kopyalar.

Buna bir örnek olarak: y = x[[0, 1, 2], :]bir kopya y = x[:3,:]döndürürken bir görünüm döndürür.

x[4:100:5, :-10:-1, None]"Normal" indeksleme gibi gerçekten çılgın bir indeksleme bile bir görünüm döndürür, bu yüzden büyük dizilerde her türlü dilimleme hilesini kullanmaktan korkmayın.

x.astype(<dtype>)yeni tür olarak verilerin bir kopyasını x.view(<dtype>)döndürürken, bir görünüm döndürür.

Bununla birlikte, buna dikkat edin ... Son derece güçlü ve kullanışlıdır, ancak temeldeki verilerin bellekte nasıl depolandığını anlamanız gerekir. Eğer bir yüzer diziniz varsa ve bunları tamslar olarak görürseniz (veya tam tersi) numpy , dizinin temeldeki bitlerini ints olarak yorumlar.

Örneğin, bu, 1.0küçük bir endian sistemde 460718241880001740864 [ 0, 0, 0, 0, 0, 0, 240, 63]bitlik bir kayan nokta olarak 64 bit int olarak ve bir uint8 olarak görüldüğünde bir dizi olarak görüldüğü anlamına gelir. Büyük dizilerde bir çeşit bit çevirme yapmanız gerektiğinde bu gerçekten güzel, gerçi ... Bellek tamponunun nasıl yorumlanacağı konusunda düşük seviyede kontrole sahipsiniz.


Çok güzel ipuçları için teşekkürler! Numpy kullanım kılavuzunu okuyordum ve neden x[np.array([1, 1, 3, 1])] += 1değiştirildiğini karıştırdım x. Şimdi anladım!
tnq177

güzel ipuçları! Başka bir sorum daha var. Bu uyuşukluğun bir kopyayı değil, sadece bir görünümü tetiklediğini nasıl kanıtlayabilirim? python'un id () bunu yapamaz görünüyor.
wuhaochi

3
@wuhaochi Eğer bbir görünüm ise a, o b.base is azaman olacaktır True. (Herhangi bir dizinin) bir kopyası her zaman olacaktırarr_copy.base is None
Jürg Merlin Spaak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.