Hãy thủ quote NumPy: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#advanced-indexingTại sao hoạt động trên những gì có vẻ là một bản sao dữ liệu sửa đổi dữ liệu gốc?
lập chỉ mục nâng cao được kích hoạt khi đối tượng lựa chọn, obj, là một đối tượng phi tuple chuỗi, một ndarray (của kiểu dữ liệu số nguyên hoặc bool), hoặc một tuple với ít nhất một đối tượng chuỗi hoặc ndarray (của kiểu dữ liệu nguyên hoặc bool). Có hai loại chỉ mục nâng cao: số nguyên và Boolean.
Lập chỉ mục nâng cao luôn trả về bản sao của dữ liệu (tương phản với cắt cơ bản trả về một chế độ xem).
Sau đó, hoạt động trên những gì được trả về bằng cách lập chỉ mục nâng cao sẽ không bao giờ sửa đổi mảng ban đầu. Và quả thực:
import numpy as np
arr = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
indexes = np.array([3, 6, 4])
slicedArr = arr[indexes]
slicedArr *= 5
arr
này in:
array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
Tuy nhiên, điều này không phải lúc nào cũng dường như là trường hợp. Oddly nếu tôi không lưu bất cứ điều gì đã được trả lại bởi các nhà điều hành []
đến một biến trung gian tôi bằng cách nào đó hoạt động trên mảng ban đầu. Hãy xem xét ví dụ sau:
import numpy as np
arr = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
indexes = np.array([3, 6, 4])
arr[indexes] *= 5
arr
in này:
array([ 0, 10, 20, 150, 200, 50, 300, 70, 80, 90])
Tôi không phàn nàn. Trên thực tế, đây là một cuộc sống tiết kiệm cho tôi. Tuy nhiên, tôi không hiểu tại sao điều này làm việc và tôi thực sự muốn hiểu điều này.
Để hiểu rõ nhất của tôi, ngay khi tôi viết arr[indexes]
Tôi đang tạo bản sao của mảng; do đó *= 5
tiếp theo sẽ hoạt động trên bản sao này chứ không phải trên mảng ban đầu. Tuy nhiên, kết quả của phép tính này nên được loại bỏ, vì nó không được ghi vào bất kỳ biến nào.
Tuy nhiên, hiển nhiên tôi đã sai.
Tôi hiểu nhầm ở đâu?
sự khác biệt là ví dụ đầu tiên của bạn đi qua '__getitem__' mà không tạo ra một bản sao bởi vì nó phải. ví dụ thứ hai của bạn không tương đương bởi vì gán cho một cái gì đó của dạng 'var [idx]' gọi 'var .__ setitem__' cho phép thực hiện gán trực tiếp cho cái gì đó không thể biểu diễn dưới dạng xem –
Ví dụ thứ hai _assigns_ to' arr [ chỉ mục], trong đó ví dụ đầu tiên không. –
Không giống như trong C++, 'a [b] = c' không thể được phân tách thành" lấy 'a [b]' "và" gán cho điều bạn đã truy xuất "; chỉ định chỉ mục là một hoạt động đơn lẻ khác với truy xuất chỉ mục và gán thông thường. – user2357112