Sử dụng chế độ xem và nhận thời gian chạy miễn phí! Mở rộng chungn-dim
các mảng thànhn+1-dim
Được giới thiệu trong NumPy1.10.0
, chúng ta có thể tận dụng numpy.broadcast_to
để tạo một 3D
khung nhìn vào 2D
mảng đầu vào một cách đơn giản . Lợi ích sẽ là không tốn thêm bộ nhớ và thời gian chạy hầu như miễn phí. Điều này sẽ rất cần thiết trong trường hợp các mảng lớn và chúng ta có thể làm việc với các khung nhìn. Ngoài ra, điều này sẽ hoạt động vớin-dim
các trường hợp .
Tôi sẽ sử dụng từ này stack
thay copy
vì người đọc có thể nhầm lẫn nó với việc sao chép các mảng tạo ra các bản sao bộ nhớ.
Xếp chồng dọc theo trục đầu tiên
Nếu chúng ta muốn xếp chồng đầu vào arr
dọc theo trục đầu tiên, giải pháp np.broadcast_to
để tạo 3D
chế độ xem sẽ là:
np.broadcast_to(arr,(3,)+arr.shape) # N = 3 here
Xếp chồng dọc theo trục thứ ba / cuối cùng
Để xếp chồng đầu vào arr
dọc theo trục thứ ba, giải pháp để tạo 3D
chế độ xem sẽ là:
np.broadcast_to(arr[...,None],arr.shape+(3,))
Nếu chúng ta thực sự cần một bản sao bộ nhớ, chúng ta luôn có thể thêm vào .copy()
đó. Do đó, các giải pháp sẽ là -
np.broadcast_to(arr,(3,)+arr.shape).copy()
np.broadcast_to(arr[...,None],arr.shape+(3,)).copy()
Đây là cách xếp chồng hoạt động cho hai trường hợp, được hiển thị cùng với thông tin hình dạng của chúng cho một trường hợp mẫu -
# 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)
(Các) giải pháp tương tự sẽ hoạt động để mở rộng n-dim
đầu vào để n+1-dim
xem đầu ra dọc theo trục đầu tiên và trục cuối cùng. Hãy cùng khám phá một số trường hợp mờ cao hơn -
Trường hợp đầu vào 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)
Trường hợp đầu vào 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)
và như thế.
Thời gian
Hãy sử dụng một 2D
trường hợp mẫu lớn và lấy thời gian và xác minh đầu ra là a view
.
# Sample input array
In [19]: arr = np.random.rand(1000,1000)
Hãy chứng minh rằng giải pháp được đề xuất là một quan điểm thực sự. Chúng tôi sẽ sử dụng xếp chồng dọc theo trục đầu tiên (kết quả sẽ rất giống với xếp chồng dọc theo trục thứ ba) -
In [22]: np.shares_memory(arr, np.broadcast_to(arr,(3,)+arr.shape))
Out[22]: True
Hãy lấy thời gian để cho thấy rằng nó hầu như miễn phí -
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
Là một lượt xem, tăng N
từ 3
lên 3000
không thay đổi gì về thời gian và cả hai đều không đáng kể về đơn vị thời gian. Do đó, hiệu quả cả về bộ nhớ và hiệu suất!
b[:,:,0]
,b[:,:,1]
vàb[:,:,2]
. Mỗi lát cắt kích thước thứ ba là một bản sao của mảng 2D ban đầu. Đây không phải là điều hiển nhiên khi chỉ nhìn vàoprint(b)
.