ทั้งสองอันเป็น method ที่ใช้เพื่อให้ได้ array ใหม่ที่มาจาก array เดิม สิ่งที่ต่างกันคือ method view เป็น shallow copy ในขณะที่ method copy เป็น deep copy
No Copy
เมื่อเราไม่ใช้ method ใดๆในการสร้าง array ใหม่จาก array เดิม แต่ใช้เครื่องหมายเท่ากับ(=) นั่นคือการ assign
ตัวอย่างการ assign array ใดๆให้อยู่ในตัวแปรอื่น เช่น
import numpy as np
x = np.arange(6)
y = x
ตัวอย่างข้างบน คือการสร้าง array ขึ้นมาก่อนโดยใช้ ndarray.arange() ซึ่งเป็น routine หนึ่งที่ใช้สร้าง array ใน NumPy โดยให้ชื่อ array ว่า x จากนั้น assign มันให้เป็น y
ผลที่ได้คือ เราจะได้ array หนึ่งอันที่สามารถเรียกโดยใช้ x หรือ y ก็ได้ มันไม่ใช่การ copy หรือคัดลอก array เราสามารถใช้ built-in function ของ Python ที่ชื่อ id(obj) ตรวจดู unique id ของวัตถุต่างๆใน Python ได้ ถ้าเปรียบให้เห็นภาพชัดๆ id(obj) เปรียบได้กับ pointer ในภาษา C ที่จะบอกตำแหน่งที่เก็บวัตถุในเมมโมรี่
ตัวอย่างการใช้ id(obj)
print(id(x))
print(id(y))
output:
4426093792
4426093792
จะเห็นว่าทั้งสอง array นี้เราได้ unique id เป็นตัวเลขชุดเดียวกัน หมายความว่าสอง array นี้เป็น array เดียวกัน แต่เรียกชื่อคนละชื่อแค่นั้นเอง
นั่นหมายความว่าการกระทำใดๆก็ตามต่อ array ใหม่จะมีผลต่อ array เดิม และการกระทำใดๆก็ตามต่อ array เดิมจะมีผลต่อ array ใหม่
y.shape = 3,2
print(x)
output:
[[0 1]
[2 3]
[4 5]]
ตัวอย่างถัดมาเราเปลี่ยน shape ของ array จากหนึ่งมิติเป็นสองมิติ โดยใช้ attribute ndarray.shape() จะเห็นได้ว่าเราเปลี่ยน shape ของ y แต่เมื่อเราแสดง shape ของ x shape ก็เปลี่ยนไปจากหนึ่งมิติเป็นสองมิติด้วย
Shallow Copy
หรือ View ใช้ method ndarray.view() เราจะได้ array ใหม่ที่มีสมาชิกหน้าตาเดียวกับ array เก่า เราสามารถ modify หรือเปลี่ยนแปลง array ทั้งสองอันได้โดยไม่กระทบต่อ array อีกอันหนึ่ง
import numpy as np
x = np.arange(6).reshape(3,2)
print(x)
print(id(x)
output:
[[0 1]
[2 3]
[4 5]]
4451389072
ในตัวอย่างด้านบนเป็นการสร้าง array ใหม่ให้ชื่อว่า x และกำหนดมิติให้เป็น 2 มิติ แบบมี 3 แถว 2 คอลัมน์
y = x.view()
print('Shape of y: ')
print(y)
print('\nid of y: ')
print(id(y))
print('\nShape of x: ')
print(x)
print('\nid of x: ')
print(id(x)
output:
Shape of y:
[[0 1]
[2 3]
[4 5]]
id of y:
4494592560
Shape of x:
[[0 1]
[2 3]
[4 5]]
id of x:
4489332416
ตัวอย่างถัดมาเป็นการใช้ method view สร้าง array ขึ้นมาอีกหนึ่งอัน โดย array ใหม่นี้จะแชร์ข้อมูลกับ array เก่าที่กำหนดไว้
ผลที่ได้จะเห็นว่า array ใหม่ที่ได้นี้มี shape เดียวกันกับอันเก่า แต่เมื่อตรวจดู unique id แล้ว พบว่าเป็นคนละไอดีกัน
y.shape = 2,3
print('\nNew shape of y: ')
print(y)
print('\nShape of x: ')
print(x)
output:
New shape of y:
[[0 1 2]
[3 4 5]]
Shape of x:
[[0 1]
[2 3]
[4 5]]
ถัดมาเป็นการเปลี่ยน shape ของ y จะเห็นได้ว่า shape ของ y เปลี่ยน แต่ shape ของ x ยังเหมือนเดิม
เปลี่ยนข้อมูลใน Arrays
การเปลี่ยนข้อมูลใน array จะส่งผลกระทบต่อ array ที่มีการแชร์ข้อมูลกัน
y[0,1] = 33
print('\nShape of y: ')
print(y)
print('\nShape of x: ')
print(x)
output:
Shape of y:
[[ 0 33 2]
[ 3 4 5]]
Shape of x:
[[ 0 33]
[ 2 3]
[ 4 5]]
ตัวอย่างด้านบนเป็นการเปลี่ยน data หรือข้อมูลใน y จะเห็นได้ว่า x เองก็โดนไปด้วย
Deep Copy
ใช้ method ndarray.copy() ได้เป็น array ใหม่จริงๆ ไม่ใช่แค่การแชร์ข้อมูลกันระหว่าง 2 arrays เท่านั้น
z = x.copy()
z[0,1] = 44
print('\nNew shape of z: ')
print(z)
print('\nShape of x: ')
print(x)
output:
New shape of z:
[[ 0 44]
[ 2 3]
[ 4 5]]
Shape of x:
[[ 0 33]
[ 2 3]
[ 4 5]
ในตัวอย่างด้านบนได้ใช้ method copy คัดลอกข้อมูลจาก array x มาสร้างเป็น array z และได้เปลี่ยนแปลงข้อมูลใน array z ทันที เมื่อเรียกแสดงผลทั้งสอง array แล้ค่าที่ได้ทั้งสองจะไม่เหมือนกัน และข้อมูลใน x ยังคงเป็นข้อมูลเดิม ไม่ได้รับผลกระทบใดๆจากการเปลี่ยนแปลงใน z