Tôi chưa sử dụng thông số out
mới này trước đây, nhưng đã làm việc với einsum
trước đây và có ý tưởng chung về cách hoạt động (hoặc ít nhất được sử dụng).
Dường như với tôi như nó khởi tạo mảng out
về 0 trước khi bắt đầu lặp lại. Điều đó sẽ giải thích cho tất cả các số 0 trong khối A[:,1:,:]
. Nếu thay vào đó tôi ban đầu out
mảng riêng biệt, các giá trị mong muốn được chèn
In [471]: B = np.ones((3,4,3),int)
In [472]: np.einsum('j, ijk->ijk', P, A[:, 1:, :], out=B[:,1:,:])
Out[472]:
array([[[ 3, 4, 5],
[ 12, 14, 16],
[ 27, 30, 33]],
[[ 15, 16, 17],
[ 36, 38, 40],
[ 63, 66, 69]],
[[ 27, 28, 29],
[ 60, 62, 64],
[ 99, 102, 105]]])
In [473]: B
Out[473]:
array([[[ 1, 1, 1],
[ 3, 4, 5],
[ 12, 14, 16],
[ 27, 30, 33]],
[[ 1, 1, 1],
[ 15, 16, 17],
[ 36, 38, 40],
[ 63, 66, 69]],
[[ 1, 1, 1],
[ 27, 28, 29],
[ 60, 62, 64],
[ 99, 102, 105]]])
Các Python phần einsum
không cho tôi biết nhiều, ngoại trừ nó như thế nào quyết định để vượt qua các mảng out
với phần c
, (là một trong những danh sách các tmp_operands
):
c_einsum (einsum_str, * tmp_operands, ** einsum_kwargs)
tôi biết rằng nó thiết lập một tương đương c-api
của np.nditer
, sử dụng str
để xác định các trục và các lần lặp.
Nó lặp cái gì đó như phần này trong hướng dẫn lặp:
https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.nditer.html#reduction-iteration
Thông báo đặc biệt là bước it.reset()
. Điều đó đặt bộ đệm out
thành 0 trước khi lặp lại. Sau đó nó lặp qua các phần tử của mảng đầu vào và mảng đầu ra, ghi các giá trị tính toán vào phần tử đầu ra. Vì nó đang thực hiện tổng sản phẩm (ví dụ: out[:] += ...
), nó phải bắt đầu bằng phương tiện chặn sạch.
Tôi đoán một chút về những gì đang thực sự xảy ra, nhưng có vẻ hợp lý với tôi rằng nó không nên ra bộ đệm đầu ra để bắt đầu. Nếu mảng đó giống với một trong các đầu vào, điều đó sẽ kết thúc với việc tính toán.
Vì vậy, tôi không nghĩ rằng phương pháp này sẽ hoạt động và giúp bạn tiết kiệm bộ nhớ. Nó cần một bộ đệm sạch để tích lũy kết quả. Khi đã xong, bạn có thể viết các giá trị trở lại vào A
. Nhưng với bản chất của một sản phẩm như dot
, bạn không thể sử dụng cùng một mảng cho đầu vào và đầu ra.
In [476]: A[:,1:,:] = np.einsum('j, ijk->ijk', P, A[:, 1:, :])
In [477]: A
Out[477]:
array([[[ 0, 1, 2],
[ 3, 4, 5],
[ 12, 14, 16],
[ 27, 30, 33]],
....)
hpaulj, @ely một trong hai bạn biết liệu đây có phải là (hoặc phải là) theo bất kỳ cách nào liên quan đến _ mới này "Kiểm tra hoạt động tại chỗ nếu đầu vào chồng chéo đầu ra và tạo thời gian để tránh vấn đề." _ Tính năng trong [numpy1.13 ] (https://docs.scipy.org/doc/numpy/release.html)? –
@PaulPanzer, tôi nghi ngờ từ các lưu ý phát hành rằng có một sự thay đổi trong xử lý '+ =' như hoạt động, và liên quan 'ufunc'. 'np.add (fib [: - 2], fib [1: -1], out = fib [2:])', https://stackoverflow.com/questions/47427603/recurrence-with-numpy, mang lại sự khác biệt kết quả dtype và phiên bản (12 v 13). Trong '13' có vẻ như toàn bộ mảng được đệm và không có đệ quy. Nhưng ngay cả với tham số 'out',' einsum' không phải là 'ufunc'. – hpaulj