2D numpy
dizim var. İlk k
satı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:
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 y
yansıtılacaktır x
ve 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 + 10
bir 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.0
neden olacaktır x
otomatik olarak zaten değilse, bir kayan noktalı diziye yukarı başına gitti. Bununla birlikte, x += 10.0
, burada x
bir 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 out
parametre 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.0
küçük bir endian sistemde 4607182418800017408
64 [ 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.
b
bir görünüm ise a
, o b.base is a
zaman olacaktır True
. (Herhangi bir dizinin) bir kopyası her zaman olacaktırarr_copy.base is None
x[np.array([1, 1, 3, 1])] += 1
değiştirildiğini karıştırdımx
. Şimdi anladım!