Penugasan numpy array dengan salinan

103

Misalnya, jika kita memiliki numpyarray A, dan kita menginginkan numpyarray Bdengan elemen yang sama.

Apa perbedaan antara metode berikut (lihat di bawah)? Kapan memori tambahan dialokasikan, dan kapan tidak?

  1. B = A
  2. B[:] = A(sama seperti B[:]=A[:]?)
  3. numpy.copy(B, A)
mrgloom
sumber

Jawaban:

127

Ketiga versi melakukan hal yang berbeda:

  1. B = A

    Ini mengikat nama baru Bke objek yang sudah ada yang dinamai A. Setelah itu, mereka merujuk ke objek yang sama, jadi jika Anda memodifikasi satu tempat, Anda akan melihat perubahan melalui yang lain juga.

  2. B[:] = A(sama seperti B[:]=A[:]?)

    Ini menyalin nilai dari Ake dalam array yang ada B. Kedua larik harus memiliki bentuk yang sama agar ini berfungsi. B[:] = A[:]melakukan hal yang sama (tetapi B = A[:]akan melakukan sesuatu yang lebih seperti 1).

  3. numpy.copy(B, A)

    Ini bukan sintaks hukum. Anda mungkin bermaksud B = numpy.copy(A). Ini hampir sama dengan 2, tetapi ini membuat array baru, daripada menggunakan kembali Barray tersebut. Jika tidak ada referensi lain ke nilai sebelumnya B, hasil akhirnya akan sama dengan 2, tetapi akan menggunakan lebih banyak memori untuk sementara selama penyalinan.

    Atau mungkin yang Anda maksud numpy.copyto(B, A), mana yang legal, dan setara dengan 2?

Blckknght
sumber
21
@Mr_and_Mrs_D: Larik numpy bekerja secara berbeda dari daftar. Memotong array tidak membuat salinan, itu hanya membuat tampilan baru pada data array yang sudah ada.
Blckknght
Apa yang dimaksud dengan but B = A[:] would do something more like 1? Menurut stackoverflow.com/a/2612815 new_list = old_list[:] ini juga merupakan salinan.
mrgloom
4
@mrgloom: Larik numpy bekerja secara berbeda dari daftar dalam hal mengiris dan menyalin isinya. Array adalah "tampilan" dari blok memori yang mendasari tempat penyimpanan nilai numerik. Melakukan slice like some_array[:]akan membuat objek array baru, tetapi objek baru itu akan menjadi tampilan memori yang sama dengan array asli, yang tidak akan disalin. Itu sebabnya saya mengatakan itu lebih seperti B = A. Ini hanya membutuhkan O(1)ruang dan waktu, bukan O(n)setiap salinan yang sebenarnya dibutuhkan.
Blckknght
27
  1. B=A membuat referensi
  2. B[:]=A membuat salinan
  3. numpy.copy(B,A) membuat salinan

dua yang terakhir membutuhkan memori tambahan.

Untuk membuat salinan dalam, Anda perlu menggunakan B = copy.deepcopy(A)

Mailerdaimon
sumber
2
Sehubungan dengan contoh kedua Anda: B[:] = Atidak tidak membuat salinan yang mendalam dari array dari objek-jenis, misalnya A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O'). Sekarang coba B[:] = A; B[0][0]=99, ini akan mengubah elemen pertama di A dan B ! Sepengetahuan saya, tidak ada cara lain untuk menjamin salinan yang dalam, bahkan dari susunan yang numpy, selaincopy.deepcopy
Rolf Bartstra
11

Ini adalah satu-satunya jawaban yang berfungsi untuk saya:

B=numpy.array(A)
Woeitg
sumber