Bir görünüm kullanın ve ücretsiz çalışma süresi kazanın! Genel n-dim
dizileri genişletmek içinn+1-dim
Sunulan numpy1.10.0
biz kaldıraç numpy.broadcast_to
sadece oluşturmak için 3D
içine bir görünümü 2D
dizi. 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-dim
durumlarda işe yarar .
Okuyucular bellek kopyalarını oluşturan dizilerin kopyalanmasıyla karıştırabileceğinden, stack
yerine kelimeyi kullanırdım copy
.
İlk eksen boyunca yığın
arr
İlk eksen boyunca girdiyi istiflemek istersek , görünümü np.broadcast_to
oluş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 3D
gö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-dim
için bir girdiyi genişletmek için işe n+1-dim
yarar. 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 2D
vaka 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 N
den 3
üzere 3000
zamanlamaları 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)
.