2013-03-28 29 views
8

Tôi đang dần cố gắng tìm hiểu sự khác biệt giữa các loại view s và copy s ở dạng gumpy, cũng như các loại có thể thay đổi và không thay đổi được.Có gán với dữ liệu mảng sao chép chỉ mục nâng cao không?

Nếu tôi truy cập vào một phần của mảng có 'advanced indexing', đó là nghĩa vụ phải trả lại một bản sao. Điều này có vẻ đúng:

In [1]: import numpy as np 
In [2]: a = np.zeros((3,3)) 
In [3]: b = np.array(np.identity(3), dtype=bool) 

In [4]: c = a[b] 

In [5]: c[:] = 9 

In [6]: a 
Out[6]: 
array([[ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.]]) 

Kể từ c chỉ là một bản sao, nó không chia sẻ dữ liệu và thay đổi nó không đột biến a. Tuy nhiên, đây là những gì confuses me:

In [7]: a[b] = 1 

In [8]: a 
Out[8]: 
array([[ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.]]) 

Vì vậy, có vẻ như, ngay cả khi tôi sử dụng chỉ mục tiên tiến, chuyển nhượng vẫn đối xử với những điều ở bên trái như một cái nhìn. Rõ ràng các a trong dòng 2 là cùng một đối tượng/dữ liệu như a trong dòng 6, kể từ khi đột biến c không có hiệu lực trên nó.

Vì vậy, câu hỏi của tôi: là a trong dòng 8 cùng một đối tượng/dữ liệu như trước (không kể đường chéo của khóa học) hoặc là một bản sao? Nói cách khác, dữ liệu của a được sao chép sang a mới hoặc dữ liệu của nó có bị thay đổi không?

Ví dụ, là nó thích:

x = [1,2,3] 
x += [4] 

hay như:

y = (1,2,3) 
y += (4,) 

Tôi không biết làm thế nào để kiểm tra này bởi vì trong cả hai trường hợp, a.flags.owndataTrue. Xin vui lòng xây dựng hoặc trả lời một câu hỏi khác nhau nếu tôi đang suy nghĩ về điều này một cách khó hiểu.

Trả lời

6

Khi bạn làm c = a[b], a.__get_item__ được gọi với đối số duy nhất là b và bất kỳ thứ gì được trả về được gán cho c.

Khi bạn làm a[b] = c, a.__setitem__ được gọi với bc làm đối số và mọi thứ được trả về sẽ bị loại bỏ âm thầm.

Vì vậy, mặc dù có cùng cú pháp a[b], cả hai biểu thức đều đang làm những việc khác nhau.Bạn có thể phân lớp ndarray, quá tải hai chức năng này và khiến chúng hoạt động khác nhau. Như được mặc định theo dạng gumpy, trước đây trả về một bản sao (nếu b là một mảng) nhưng sau đó sửa đổi a tại chỗ.

+0

Tôi nghĩ rằng nó có giá trị để chỉ ra một cách rõ ràng trong tài liệu gọn gàng thực tế là ngay cả chỉ mục nâng cao khi được sử dụng như lvalue sẽ sửa đổi mảng ban đầu. – vehsakul

3

Vâng, đó là cùng một đối tượng. Dưới đây là cách bạn kiểm tra:

>>> a 
array([[ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.]]) 
>>> a2 = a 
>>> a[b] = 1 
>>> a2 is a 
True 
>>> a2 
array([[ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.]]) 

Gán một số biểu thức bằng Python không giống như đọc giá trị của biểu thức đó. Khi bạn làm c = a[b], với a[b] ở bên phải dấu bằng, nó sẽ trả về một đối tượng mới. Khi bạn làm a[b] = 1, với a[b] ở bên trái dấu bằng, nó sửa đổi đối tượng gốc.

Thực tế, biểu thức như a[b] = 1không thể thay đổi tên a bị ràng buộc. Mã chỉ xử lý obj[index] = value chỉ được biết đối tượng obj, không phải tên được sử dụng để chỉ đối tượng đó, vì vậy nó không thể thay đổi tên đó đề cập đến.

Các vấn đề liên quan