การกำหนดอาร์เรย์ที่เป็นตัวเลขพร้อมสำเนา


108

ตัวอย่างเช่นถ้าเรามีnumpyอาร์เรย์Aและเราต้องการnumpyอาร์เรย์ที่Bมีองค์ประกอบเดียวกัน

อะไรคือความแตกต่างระหว่างวิธีการต่อไปนี้ (ดูด้านล่าง)? หน่วยความจำเพิ่มเติมจะถูกจัดสรรเมื่อใดและเมื่อใด

  1. B = A
  2. B[:] = A(เช่นเดียวกับB[:]=A[:]?)
  3. numpy.copy(B, A)

คำตอบ:


135

ทั้งสามเวอร์ชันทำสิ่งที่แตกต่างกัน:

  1. B = A

    นี้ผูกชื่อใหม่ไปยังวัตถุที่มีอยู่ที่มีชื่ออยู่แล้วB Aหลังจากนั้นพวกเขาอ้างถึงวัตถุเดียวกันดังนั้นหากคุณแก้ไขสิ่งหนึ่งในสถานที่คุณจะเห็นการเปลี่ยนแปลงผ่านอีกวัตถุด้วย

  2. B[:] = A(เช่นเดียวกับB[:]=A[:]?)

    สำเนานี้ค่าจากเป็นอาร์เรย์ที่มีอยู่A Bอาร์เรย์ทั้งสองต้องมีรูปร่างเหมือนกันจึงจะทำงานได้ B[:] = A[:]ทำสิ่งเดียวกัน (แต่B = A[:]จะทำบางอย่างมากกว่าเช่น 1)

  3. numpy.copy(B, A)

    นี่ไม่ใช่ไวยากรณ์ทางกฎหมาย B = numpy.copy(A)คุณอาจหมายถึง เกือบจะเหมือนกับ 2 แต่จะสร้างอาร์เรย์ใหม่แทนที่จะใช้Bอาร์เรย์ซ้ำ หากไม่มีการอ้างอิงอื่นไปยังBค่าก่อนหน้าผลลัพธ์สุดท้ายจะเหมือนกับ 2 แต่จะใช้หน่วยความจำมากกว่าชั่วคราวในระหว่างการคัดลอก

    หรือบางทีคุณอาจหมายถึงnumpy.copyto(B, A)ซึ่งถูกกฎหมายและเทียบเท่ากับ 2?


21
@Mr_and_Mrs_D: อาร์เรย์ Numpy ทำงานแตกต่างจากรายการ การแบ่งอาร์เรย์ไม่ได้สร้างสำเนา แต่เป็นการสร้างมุมมองใหม่บนข้อมูลของอาร์เรย์ที่มีอยู่
Blckknght

หมายถึงbut B = A[:] would do something more like 1อะไร? ตามstackoverflow.com/a/2612815 new_list = old_list[:]นี้เป็นสำเนาด้วย
mrgloom

4
@mrgloom: อาร์เรย์ที่เป็นตัวเลขจะทำงานแตกต่างจากรายการเมื่อต้องแบ่งส่วนและคัดลอกเนื้อหา อาร์เรย์คือ "มุมมอง" ของบล็อกหน่วยความจำพื้นฐานที่เก็บค่าตัวเลข การทำสไลซ์some_array[:]จะเป็นการสร้างอ็อบเจกต์อาร์เรย์ใหม่ แต่อ็อบเจ็กต์ใหม่นั้นจะเป็นมุมมองของหน่วยความจำเดียวกันกับอาร์เรย์เดิมซึ่งจะไม่ถูกคัดลอก B = Aนั่นเป็นเหตุผลที่ผมบอกว่ามันมากขึ้นเช่น ต้องใช้O(1)พื้นที่และเวลาเท่านั้นแทนที่จะO(n)ต้องใช้สำเนาจริงแต่ละชุด
Blckknght

ที่ต้องการ 'คัดลอก' B = A.copy()วิธีการตามเอกสารที่เป็น B = A.copy(order='k')แต่ฟอร์มนี้ไม่ได้รักษาลำดับโดยค่าเริ่มต้นที่คุณต้องการ
Howard Lovatt

27
  1. B=A สร้างข้อมูลอ้างอิง
  2. B[:]=A ทำสำเนา
  3. numpy.copy(B,A) ทำสำเนา

สองคนสุดท้ายต้องการหน่วยความจำเพิ่มเติม

ในการทำสำเนาลึกคุณต้องใช้ B = copy.deepcopy(A)


2
หมายถึงตัวอย่างที่สองของคุณ: B[:] = Aไม่ได้A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O')ทำสำเนาลึกของอาร์เรย์ของวัตถุชนิดเช่น ตอนนี้ลองB[:] = A; B[0][0]=99สิ่งนี้จะเปลี่ยนองค์ประกอบแรกทั้งในA และ B ! สำหรับความรู้ของฉันไม่มีวิธีอื่นใดในการรับประกันสำเนาที่ลึกแม้จะเป็นอาร์เรย์ที่เป็นตัวเลขมากกว่าcopy.deepcopy
Rolf Bartstra

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.