Bir görünüm kullanın ve ücretsiz çalışma süresi kazanın! Genel n-dimdizileri genişletmek içinn+1-dim
Sunulan numpy1.10.0 biz kaldıraç numpy.broadcast_tosadece oluşturmak için 3Diçine bir görünümü 2Ddizi. Bunun faydası, fazladan bellek yükü ve neredeyse ücretsiz çalışma süresi olacaktır. Bu, dizilerin büyük olduğu ve görünümlerle çalışmamızın uygun olduğu durumlarda çok önemlidir. Ayrıca, bu genel n-dimdurumlarda işe yarar .
Okuyucular bellek kopyalarını oluşturan dizilerin kopyalanmasıyla karıştırabileceğinden, stackyerine kelimeyi kullanırdım copy.
İlk eksen boyunca yığın
arrİlk eksen boyunca girdiyi istiflemek istersek , görünümü np.broadcast_tooluşturmanın çözümü 3Dşu olacaktır:
np.broadcast_to(arr,(3,)+arr.shape) # N = 3 here
Üçüncü / son eksen boyunca yığın
Girişleri arrüçüncü eksen boyunca istiflemek için 3Dgörünüm oluşturmanın çözümü şu olacaktır:
np.broadcast_to(arr[...,None],arr.shape+(3,))
Aslında bir bellek kopyasına ihtiyacımız varsa, her zaman .copy()oraya ekleyebiliriz . Dolayısıyla çözümler şu şekilde olacaktır -
np.broadcast_to(arr,(3,)+arr.shape).copy()
np.broadcast_to(arr[...,None],arr.shape+(3,)).copy()
Örnek bir vaka için şekil bilgileriyle gösterilen iki kasa için istifleme şu şekilde çalışır:
# Create a sample input array of shape (4,5)
In [55]: arr = np.random.rand(4,5)
# Stack along first axis
In [56]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[56]: (3, 4, 5)
# Stack along third axis
In [57]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[57]: (4, 5, 3)
Aynı çözüm (ler), çıktıyı ilk ve son eksenler boyunca görüntülemek n-dimiçin bir girdiyi genişletmek için işe n+1-dimyarar. Daha yüksek karanlık durumları inceleyelim -
3D giriş durumu:
In [58]: arr = np.random.rand(4,5,6)
# Stack along first axis
In [59]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[59]: (3, 4, 5, 6)
# Stack along last axis
In [60]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[60]: (4, 5, 6, 3)
4D giriş durumu:
In [61]: arr = np.random.rand(4,5,6,7)
# Stack along first axis
In [62]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[62]: (3, 4, 5, 6, 7)
# Stack along last axis
In [63]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[63]: (4, 5, 6, 7, 3)
ve bunun gibi.
Zamanlamalar
Büyük bir örnek 2Dvaka kullanalım ve zamanlamaları alalım ve çıktının bir view.
# Sample input array
In [19]: arr = np.random.rand(1000,1000)
Önerilen çözümün gerçekten bir görüş olduğunu kanıtlayalım. İlk eksen boyunca istiflemeyi kullanacağız (sonuçlar üçüncü eksen boyunca istifleme için çok benzer olacaktır) -
In [22]: np.shares_memory(arr, np.broadcast_to(arr,(3,)+arr.shape))
Out[22]: True
Neredeyse ücretsiz olduğunu göstermek için zamanlamaları alalım -
In [20]: %timeit np.broadcast_to(arr,(3,)+arr.shape)
100000 loops, best of 3: 3.56 µs per loop
In [21]: %timeit np.broadcast_to(arr,(3000,)+arr.shape)
100000 loops, best of 3: 3.51 µs per loop
Bir görünüm olmak artan Nden 3üzere 3000zamanlamaları değiştirildi hiçbir şey ve her iki zamanlama birimleri önemsizdir. Bu nedenle hem bellek hem de performans açısından verimli!
b[:,:,0],b[:,:,1]veb[:,:,2]. Her bir üçüncü boyut dilimi, orijinal 2D dizinin bir kopyasıdır. Bu sadece bakmak kadar açık değilprint(b).