2014-04-23 18 views
11

Tôi cố gắng để sử dụng resize trên một mảng theo cách này:Numpy, mảng không có dữ liệu riêng?

a = np.array([1,2,3,4,5,6], dtype=np.uint8) 
a.resize(4,2) 
print a 

và đầu ra là Ok (tôi muốn nói rằng không có lỗi)!. Nhưng khi tôi chạy mã này:

a = np.array([1,2,3,4,5,6], dtype=np.uint8).reshape(2,3) 
a.resize(4,2) 
print a 

nó đã dẫn đến một lỗi, nói rằng, ValueError: cannot resize this array: it does not own its data

Câu hỏi của tôi: tại sao sau khi áp dụng reshape quyền sở hữu của mảng được thay đổi? Quyền sở hữu được cấp cho ai! reshape không tạo ra một bộ nhớ mới và nó đang thực hiện hoạt động của nó trên cùng một bộ nhớ mảng! Vậy tại sao quyền sở hữu sẽ thay đổi?

Tôi đọc np.reshapendarray.resize tài liệu nhưng tôi không thể hiểu lý do. Tôi đọc this post. Tôi có thể kiểm tra ndarray.flags trước khi áp dụng phương thức resize.

Trả lời

11

Hãy bắt đầu với những điều sau đây:

>>> a = np.array([1,2,3,4,5,6], dtype=np.uint8) 
>>> b = a.reshape(2,3) 
>>> b[0,0] = 5 
>>> a 
array([5, 2, 3, 4, 5, 6], dtype=uint8) 

tôi có thể thấy ở đây là mảng b không phải là mảng riêng của mình, nhưng chỉ đơn giản là một cái nhìn của a (chỉ cần một cách khác để hiểu được "OWNDATA" cờ). Để đặt đơn giản cả hai số ab tham chiếu cùng một dữ liệu trong bộ nhớ, nhưng b đang xem a với hình dạng khác. Gọi hàm resize như ndarray.resize cố gắng thay đổi mảng tại chỗ, như b chỉ là một cái nhìn của a này là không được phép, kể từ resize định nghĩa:

Mục đích của việc kiểm tra tính tham khảo là làm cho chắc chắn bạn không sử dụng mảng này làm bộ đệm cho đối tượng Python khác và sau đó tái phân bổ bộ nhớ.


Để tránh các vấn đề của bạn, bạn có thể gọi resize từ NumPy (không phải là một thuộc tính của một ndarray) mà sẽ phát hiện vấn đề này và sao chép dữ liệu tự động:

>>> np.resize(b,(4,2)) 
array([[5, 2], 
     [3, 4], 
     [5, 6], 
     [5, 2]], dtype=uint8) 

Edit: Theo CT Zhu đề cập chính xác np.resizendarray.resize thêm dữ liệu theo hai cách khác nhau. Để tái tạo hành vi mong đợi như ndarray.resize bạn sẽ phải làm như sau:

>>> c = b.copy() 
>>> c.resize(4,2) 
>>> c 
array([[5, 2], 
     [3, 4], 
     [5, 6], 
     [0, 0]], dtype=uint8) 
+0

'a = np.array ([1,2,3,4,5,6], dtype = np.uint8) ', những hai kết quả khác nhau: 'np.resize (a, (4,2))' 'a.resize (4,2); in a'. Nó không phải là một circumvent –

+0

@CTZhu Tốt điểm họ tăng hình dạng theo hai cách khác nhau. – Daniel

+3

Một cách khác là sửa đổi thuộc tính 'hình dạng' của mảng. (ví dụ: 'a.shape = (2, 3)') Việc này định dạng lại tại chỗ mà không tạo chế độ xem mới. –

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