Gán mảng khó hiểu với bản sao


103

Ví dụ, nếu chúng ta có một numpymảng Avà chúng ta muốn một numpymảng Bcó các phần tử giống nhau.

Sự khác biệt giữa các phương pháp sau (xem bên dưới) là gì? Khi nào bộ nhớ bổ sung được cấp phát và khi nào thì không?

  1. B = A
  2. B[:] = A(giống như B[:]=A[:]?)
  3. numpy.copy(B, A)

Câu trả lời:


127

Cả ba phiên bản đều làm những việc khác nhau:

  1. B = A

    Điều này liên kết một tên mới Bvới đối tượng hiện có đã được đặt tên A. Sau đó, chúng đề cập đến cùng một đối tượng, vì vậy nếu bạn sửa đổi một đối tượng tại chỗ, bạn cũng sẽ thấy sự thay đổi thông qua đối tượng còn lại.

  2. B[:] = A(giống như B[:]=A[:]?)

    Điều này sao chép các giá trị từ Amột mảng hiện có B. Hai mảng phải có cùng hình dạng để điều này hoạt động. B[:] = A[:]làm điều tương tự (nhưng B = A[:]sẽ làm điều gì đó giống như 1).

  3. numpy.copy(B, A)

    Đây không phải là cú pháp hợp pháp. Có thể bạn muốn nói B = numpy.copy(A). Điều này gần giống như 2, nhưng nó tạo ra một mảng mới, thay vì sử dụng lại Bmảng. Nếu không có tham chiếu nào khác đến Bgiá trị trước đó , kết quả cuối cùng sẽ giống như 2, nhưng nó sẽ tạm thời sử dụng nhiều bộ nhớ hơn trong quá trình sao chép.

    Hoặc có thể ý bạn là numpy.copyto(B, A), cái nào là hợp pháp và tương đương với 2?


21
@Mr_and_Mrs_D: Mảng Numpy hoạt động khác với danh sách. Việc cắt một mảng không tạo ra một bản sao, nó chỉ tạo một dạng xem mới trên dữ liệu của mảng hiện có.
Blckknght 29/09/17

Nghĩa là gì but B = A[:] would do something more like 1? Theo stackoverflow.com/a/2612815 new_list = old_list[:] này cũng là một bản sao.
mrgloom

4
@mrgloom: Mảng Numpy hoạt động khác với danh sách khi nói đến việc cắt và sao chép nội dung của chúng. Mảng là một "khung nhìn" của một khối bộ nhớ bên dưới nơi các giá trị số được lưu trữ. Thực hiện một lát như some_array[:]sẽ tạo ra một đối tượng mảng mới, nhưng đối tượng mới đó sẽ là một khung nhìn của cùng một bộ nhớ với mảng ban đầu, sẽ không được sao chép. Đó là lý do tại sao tôi nói nó giống hơn B = A. Nó chỉ cần O(1)không gian và thời gian, thay vì O(n)mỗi bản sao thật sẽ cần.
Blckknght

27
  1. B=A tạo một tài liệu tham khảo
  2. B[:]=A tạo một bản sao
  3. numpy.copy(B,A) tạo một bản sao

hai cuối cùng cần thêm bộ nhớ.

Để tạo một bản sao sâu, bạn cần sử dụng B = copy.deepcopy(A)


2
Đề cập đến ví dụ thứ hai của mình: B[:] = Akhông không tạo một bản sao sâu sắc về mảng các đối tượng loại, ví dụ A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O'). Bây giờ hãy thử B[:] = A; B[0][0]=99, điều này sẽ thay đổi phần tử đầu tiên trong cả A và B ! Theo hiểu biết của tôi, không có cách nào khác để đảm bảo một bản sao sâu, thậm chí của một NumPy mảng, hơncopy.deepcopy
Rolf Bartstra

11

Đây là câu trả lời làm việc duy nhất cho tôi:

B=numpy.array(A)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.