có lẽ cách sạch nhất là sử dụng np.repeat
:
a = np.array([[1, 2], [1, 2]])
print(a.shape)
# (2, 2)
# indexing with np.newaxis inserts a new 3rd dimension, which we then repeat the
# array along, (you can achieve the same effect by indexing with None, see below)
b = np.repeat(a[:, :, np.newaxis], 3, axis=2)
print(b.shape)
# (2, 2, 3)
print(b[:, :, 0])
# [[1 2]
# [1 2]]
print(b[:, :, 1])
# [[1 2]
# [1 2]]
print(b[:, :, 2])
# [[1 2]
# [1 2]]
có nói rằng, bạn thường có thể tránh lặp lại các mảng của bạn hoàn toàn bằng cách sử dụng broadcasting. Ví dụ, chúng ta hãy nói rằng tôi muốn thêm một vector (3,)
:
c = np.array([1, 2, 3])
để a
. Tôi có thể sao chép nội dung của a
3 lần trong thứ nguyên thứ ba, sau đó sao chép nội dung của c
hai lần ở cả thứ nguyên đầu tiên và thứ hai, sao cho cả hai mảng của tôi là (2, 2, 3)
, sau đó tính tổng của chúng. Tuy nhiên, nó đơn giản hơn nhiều và nhanh hơn để làm điều này:
d = a[..., None] + c[None, None, :]
Ở đây, a[..., None]
có hình (2, 2, 1)
và c[None, None, :]
có hình (1, 1, 3)
*. Khi tôi tính toán Tóm lại, kết quả được 'phát sóng' ra dọc theo kích thước của kích thước 1, đem lại cho tôi một kết quả của hình dạng (2, 2, 3)
:
print(d.shape)
# (2, 2, 3)
print(d[..., 0]) # a + c[0]
# [[2 3]
# [2 3]]
print(d[..., 1]) # a + c[1]
# [[3 4]
# [3 4]]
print(d[..., 2]) # a + c[2]
# [[4 5]
# [4 5]]
Broadcasting là một kỹ thuật rất mạnh mẽ bởi vì nó tránh được sự bổ sung trên không liên quan đến việc tạo ra các bản sao lặp lại của các mảng đầu vào của bạn trong bộ nhớ.
* Mặc dù tôi bao gồm họ cho rõ ràng, các chỉ số None
vào c
là không thực sự cần thiết - bạn cũng có thể làm a[..., None] + c
, ví dụ: phát sóng một mảng (2, 2, 1)
chống lại một mảng (3,)
. Điều này là do nếu một trong các mảng có kích thước nhỏ hơn kích thước khác thì chỉ có kích thước trailing của hai mảng cần tương thích. Để đưa ra một ví dụ phức tạp hơn:
a = np.ones((6, 1, 4, 3, 1)) # 6 x 1 x 4 x 3 x 1
b = np.ones((5, 1, 3, 2)) # 5 x 1 x 3 x 2
result = a + b # 6 x 5 x 4 x 3 x 2
Để xác minh rằng điều này thực sự mang lại cho kết quả đúng, bạn cũng có thể in ra 'b [:,:, 0] ',' b [:,:, 1] ', và' b [:,:, 2] '. Mỗi lát thứ nguyên thứ ba là một bản sao của mảng 2D gốc. Điều này không rõ ràng khi nhìn vào 'print (b)'. – ely
Đây là một câu trả lời tuyệt vời !! Cảm ơn bạn! – drg