Скористайтеся поданням та отримайте безкоштовний час виконання! Розширити родовеn-dim
масиви доn+1-dim
Представлений у NumPy1.10.0
, ми можемо використовувати numpy.broadcast_to
просто генерування 3D
подання у 2D
вхідний масив. Користь не матиме зайвих витрат на пам'ять та практично безкоштовне виконання. Це було б вкрай важливо у випадках, коли масиви великі, і ми добре працюємо з думками. Крім того, це працювало б із загальнимn-dim
випадками.
Я б використав це слово stack
замістьcopy
, оскільки читачі можуть переплутати його з копіюванням масивів, які створюють копії пам'яті.
Складіть уздовж першої осі
Якщо ми хочемо скласти вхід arr
по першій осі, рішенням np.broadcast_to
для створення 3D
представлення буде:
np.broadcast_to(arr,(3,)+arr.shape) # N = 3 here
Складіть уздовж третьої / останньої осі
Для arr
складання вводу вздовж третьої осі рішенням для створення 3D
перегляду було б -
np.broadcast_to(arr[...,None],arr.shape+(3,))
Якщо нам справді потрібна копія пам'яті, ми завжди можемо її додати .copy()
. Отже, рішення були б -
np.broadcast_to(arr,(3,)+arr.shape).copy()
np.broadcast_to(arr[...,None],arr.shape+(3,)).copy()
Ось як працює укладання для двох випадків, показана з їх формою для зразка випадку -
# 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)
Це ж рішення (и) буде працювати над розширенням n-dim
входу для n+1-dim
перегляду результатів по першій та останній осях. Давайте вивчимо кілька вищих темних випадків -
3D-вхід:
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 вхідний корпус:
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)
і так далі.
Хронометраж
Давайте скористаємося великим зразком 2D
випадку і отримаємо терміни та перевіримо, чи є вихід view
.
# Sample input array
In [19]: arr = np.random.rand(1000,1000)
Доведемо, що запропоноване рішення справді є думкою. Ми будемо використовувати укладання вздовж першої осі (результати будуть дуже схожі на укладання вздовж третьої осі) -
In [22]: np.shares_memory(arr, np.broadcast_to(arr,(3,)+arr.shape))
Out[22]: True
Давайте визначимо, що це практично безкоштовно -
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
Будучи видом, збільшуючи N
від , 3
щоб 3000
змінилися ні на таймингах і обидва є незначними по об'єктах синхронізації. Отже, ефективні як у пам’яті, так і в продуктивності!
b[:,:,0]
,b[:,:,1]
іb[:,:,2]
. Кожен третій розмірний фрагмент є копією вихідного 2D масиву. Це не так очевидно, просто дивлячисьprint(b)
.