Kopyalama ile uyuşmayan dizi ataması


103

Örneğin, bir numpydizimiz varsa ve aynı elemanlara sahip Abir numpydizi istiyorsak B.

Aşağıdaki (aşağıya bakın) yöntemler arasındaki fark nedir? Ek bellek ne zaman tahsis edilir ve ne zaman tahsis edilmez?

  1. B = A
  2. B[:] = A(aynı B[:]=A[:]?)
  3. numpy.copy(B, A)

Yanıtlar:


127

Her üç sürüm de farklı şeyler yapar:

  1. B = A

    Bu, Bönceden adlandırılmış mevcut nesneye yeni bir ad bağlar A. Daha sonra aynı nesneye atıfta bulunurlar, bu nedenle birini yerinde değiştirirseniz, değişikliği diğerinde de görürsünüz.

  2. B[:] = A(aynı B[:]=A[:]?)

    Bu, değerleri Amevcut bir diziye kopyalar B. Bunun çalışması için iki dizinin aynı şekle sahip olması gerekir. B[:] = A[:]aynı şeyi yapar (ancak B = A[:]1'e benzer bir şey yapar ).

  3. numpy.copy(B, A)

    Bu yasal sözdizimi değildir. Muhtemelen demek istedin B = numpy.copy(A). Bu neredeyse 2 ile aynıdır, ancak diziyi yeniden kullanmak yerine yeni bir dizi oluşturur B. Önceki Bdeğere başka referanslar yoksa, sonuç 2 ile aynı olur, ancak kopyalama sırasında geçici olarak daha fazla bellek kullanır.

    Ya da belki numpy.copyto(B, A)hangisinin yasal olduğunu ve 2'ye eşdeğer olduğunu mu kastediyorsunuz ?


21
@Mr_and_Mrs_D: Numpy dizileri listelerden farklı çalışır. Bir diziyi dilimlemek bir kopya oluşturmaz, sadece mevcut dizinin verileri üzerinde yeni bir görünüm oluşturur.
Blckknght

İle kastedilen nedir but B = A[:] would do something more like 1? Bu stackoverflow.com/a/2612815'e göre new_list = old_list[:] de bir kopyadır.
mrgloom

4
@mrgloom: Numpy dizileri, içeriklerini dilimlemek ve kopyalamak söz konusu olduğunda listelerden farklı çalışır. Bir dizi, sayısal değerlerin depolandığı temel bir bellek bloğunun "görünümü" dür. Bir dilim benzeri yapmak, some_array[:]yeni bir dizi nesnesi yaratacaktır, ancak bu yeni nesne, kopyalanmamış olan orijinal diziyle aynı belleğin bir görünümü olacaktır. Bu yüzden daha çok benziyor dedim B = A. Her bir gerçek kopyanın ihtiyaç duyacağı O(1)alan yerine yalnızca yer ve zaman alır O(n).
Blckknght

27
  1. B=A referans oluşturur
  2. B[:]=A bir kopya yapar
  3. numpy.copy(B,A) bir kopya yapar

son ikisi ek belleğe ihtiyaç duyar.

Derin bir kopya oluşturmak için kullanmanız gerekir B = copy.deepcopy(A)


2
İkinci örneğe atıfta: B[:] = Ayok değil nesne tipi, örn dizileri derin bir kopyasını yapmak A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O'). Şimdi deneyin B[:] = A; B[0][0]=99, bu hem A hem de B'deki ilk öğeyi değiştirecek ! Bildiğim copy.deepcopy
kadarıyla

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.