NumPy reshape (): วิธีปรับรูปร่าง NumPy Array ใน Python

เผยแพร่แล้ว: 2022-04-20

ในบทช่วยสอนนี้ คุณจะได้เรียนรู้วิธีใช้ NumPy reshape() เพื่อเปลี่ยนรูปร่างอาร์เรย์ NumPy โดยไม่ต้องเปลี่ยนข้อมูลเดิม

เมื่อทำงานกับอาร์เรย์ Numpy คุณอาจต้องการเปลี่ยนอาร์เรย์ที่มีอยู่ให้เป็นอาร์เรย์ที่มีมิติต่างกัน สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อคุณแปลงข้อมูลในหลายขั้นตอน

และ NumPy reshape reshape() ช่วยให้คุณทำได้อย่างง่ายดาย ในอีกไม่กี่นาทีข้างหน้า คุณจะได้เรียนรู้ไวยากรณ์การใช้ reshape() และปรับรูปร่างอาร์เรย์ให้เป็นมิติต่างๆ

Reshaping ใน NumPy Array คืออะไร?

เมื่อทำงานกับอาร์เรย์ NumPy คุณอาจต้องการสร้างอาร์เรย์ตัวเลข 1 มิติก่อน แล้วปรับรูปร่างให้เป็นอาร์เรย์ที่มีมิติที่ต้องการ

สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อไม่ทราบขนาดของอาร์เรย์ใหม่ตั้งแต่แรกหรือมีการอนุมานระหว่างการดำเนินการ หรืออาจเป็นไปได้ว่าขั้นตอนการประมวลผลข้อมูลบางอย่างต้องการให้อินพุตมีรูปร่างเฉพาะ

นี่คือจุดที่การ ปรับรูปร่างใหม่ มีประโยชน์

ตัวอย่างเช่น ลองพิจารณาภาพประกอบต่อไปนี้ เรามีเวกเตอร์—อาร์เรย์หนึ่งมิติที่มีองค์ประกอบ 6 ตัว และเราสามารถจัดรูปแบบใหม่เป็นอาร์เรย์ของรูปร่าง 2×3, 3×2, 6×1 และอื่นๆ

หุ่นเป๊ะปัง

️ เพื่อทำตามตัวอย่างในบทช่วยสอนนี้ คุณต้องติดตั้ง Python และ NumPy หากคุณยังไม่มี NumPy โปรดดูคู่มือการติดตั้ง NumPy ของเรา

ตอนนี้คุณสามารถนำเข้า NumPy ภายใต้นามแฝง np โดยเรียกใช้: import numpy as np

มาเริ่มเรียนรู้ไวยากรณ์กันในหัวข้อถัดไป

ไวยากรณ์ของ NumPy reshape()

นี่คือรูปแบบการใช้ NumPy reshape():

 np.reshape(arr, newshape, order = 'C'|'F'|'A')
  • arr เป็นวัตถุอาร์เรย์ NumPy ที่ถูกต้อง นี่คืออาร์เรย์ที่จะเปลี่ยนโฉมหน้า
  • newshape คือรูปร่างของอาร์เรย์ใหม่ อาจเป็นจำนวนเต็มหรือทูเพิลก็ได้
  • เมื่อ newshape เป็นจำนวนเต็ม อาร์เรย์ที่ส่งคืนจะเป็นแบบมิติเดียว
  • order หมายถึงลำดับที่คุณต้องการอ่านในองค์ประกอบของอาร์เรย์ที่จะเปลี่ยนรูปร่าง
  • ค่าเริ่มต้นคือ 'C' ซึ่งหมายความว่าองค์ประกอบของอาร์เรย์ดั้งเดิมจะถูกอ่านตามลำดับการสร้างดัชนีแบบ C (เริ่มต้นด้วย 0)
  • 'F' หมายถึงการจัดทำดัชนีเหมือน Fortran (เริ่มต้นด้วย 1) และ 'A' จะอ่านในองค์ประกอบตามลำดับ C-like หรือ Fortran ขึ้นอยู่กับเลย์เอาต์หน่วยความจำของอาร์เรย์ arr

np.reshape() ส่งคืนอะไร

จะส่งกลับ มุมมอง ที่เปลี่ยนรูปร่างของอาร์เรย์เดิมถ้าเป็นไปได้ มิฉะนั้นจะส่งกลับ สำเนา ของอาร์เรย์

ในบรรทัดด้านบน เรากล่าวว่า NumPy reshape reshape() จะพยายามส่งคืน มุมมอง ทุกครั้งที่ทำได้ มิฉะนั้นจะส่งคืน สำเนา มาพูดถึงความแตกต่างระหว่างมุมมองและสำเนากัน

ดูเทียบกับสำเนาของ NumPy Arrays

ตามชื่อที่แนะนำ สำเนา คือสำเนาของอาร์เรย์ต้นฉบับ และการเปลี่ยนแปลงใดๆ ที่ทำกับสำเนาจะ ไม่มีผล กับอาร์เรย์ดั้งเดิม

ในทางกลับกัน view หมายถึงมุมมองที่เปลี่ยนรูปร่างของอาร์เรย์ดั้งเดิม ซึ่งหมายความว่าการเปลี่ยนแปลงใดๆ ที่เกิดขึ้นกับมุมมองจะส่งผลต่ออาร์เรย์ดั้งเดิมและในทางกลับกันด้วย

ใช้ NumPy reshape() เพื่อปรับรูปร่าง 1D Array เป็น 2D Arrays

#1. เริ่มต้นด้วยการสร้างอาร์เรย์ตัวอย่างโดยใช้ np.arange()

เราต้องการอาร์เรย์ 12 ตัวเลข ตั้งแต่ 1 ถึง 12 เรียกว่า arr1 เนื่องจากฟังก์ชัน NumPy arange() ไม่รวมปลายทางโดยค่าเริ่มต้น ให้ตั้งค่าหยุดเป็น 13

ตอนนี้ให้เราใช้ไวยากรณ์ข้างต้น และปรับรูปร่าง arr1 ด้วยองค์ประกอบ 12 องค์ประกอบเป็นอาร์เรย์ 2 มิติของรูปร่าง (4,3) เรียกนี่ว่า arr2 มี 4 แถว 3 คอลัมน์

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr2 = np.reshape(arr1,(4,3)) print("\nReshaped array:") print(arr2)

เรามาดูอาร์เรย์ดั้งเดิมและที่ปรับโฉมใหม่กัน

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]]

แทนที่จะส่งผ่านอาร์เรย์เป็นอาร์กิวเมนต์ np.reshape() คุณยังสามารถเรียก .reshape() ในอาร์เรย์ดั้งเดิมได้

คุณสามารถเรียกใช้ dir(arr1) และจะแสดงรายการวิธีการและแอตทริบิวต์ที่เป็นไปได้ทั้งหมดที่คุณสามารถใช้กับวัตถุอาร์เรย์ arr1

 dir(arr1) # Output [ ... ... 'reshape' ... .. ]

ในเซลล์โค้ดด้านบน คุณจะเห็นว่า .reshape() เป็นวิธีที่ถูกต้องสำหรับใช้กับอาร์เรย์ NumPy arr1 ที่มีอยู่

️ ดังนั้น คุณยังสามารถใช้ไวยากรณ์แบบง่ายต่อไปนี้เพื่อเปลี่ยนรูปร่างอาร์เรย์ NumPy

 arr.reshape(d0,d1,...,dn) # where: # d0, d1,..,dn are the dimensions of the reshaped array # d0 * d1 * ...* dn = N, the number of elements in arr

สำหรับส่วนที่เหลือของบทช่วยสอนนี้ ให้เราใช้ไวยากรณ์นี้ในตัวอย่างของเรา

#2. ลองเปลี่ยนเวกเตอร์ 12 องค์ประกอบของเราเป็นอาร์เรย์ 12 x 1

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr3 = arr1.reshape(12,1) print("\nReshaped array:") print(arr3)

ในผลลัพธ์ด้านล่าง คุณจะเห็นว่าอาร์เรย์ได้รับการเปลี่ยนรูปร่างตามต้องการ

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9] [10] [11] [12]]

แล้วเราจะตรวจสอบได้อย่างไรว่าเราได้รับสำเนาหรือมุมมอง?

หากต้องการตรวจสอบ คุณสามารถเรียกแอตทริบิวต์ base บนอาร์เรย์ที่ส่งคืนได้

  • หากอาร์เรย์เป็นสำเนา แอตทริบิวต์ base จะเป็น None
  • หากอาร์เรย์เป็นมุมมอง แอตทริบิวต์ base จะเป็นอาร์เรย์ดั้งเดิม

มาตรวจสอบกันอย่างรวดเร็ว

 arr3.base # Output array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

อย่างที่คุณเห็น แอตทริบิวต์ base ของ arr3 จะคืนค่าอาร์เรย์เดิม ซึ่งหมายความว่าเราได้รับ มุมมอง ของอาร์เรย์ดั้งเดิมแล้ว

#3. ทีนี้ มาลองเปลี่ยนเวกเตอร์เป็นอาร์เรย์ 2 x 6 อื่นที่ถูกต้องกัน

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr4 = arr1.reshape(2,6) print("\nReshaped array:") print(arr4)

และนี่คือผลลัพธ์:

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[ 1 2 3 4 5 6] [ 7 8 9 10 11 12]]

ในส่วนถัดไป มาเปลี่ยนรูปร่าง arr1 ให้เป็นอาร์เรย์ 3 มิติกัน

ใช้ NumPy reshape() เพื่อปรับรูปร่าง 1D Array เป็น 3D Arrays

ในการปรับรูปร่าง arr1 เป็นอาร์เรย์ 3 มิติ ให้เรากำหนดขนาดที่ต้องการเป็น (1, 4, 3)

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr3D = arr1.reshape(1,4,3) print("\nReshaped array:") print(arr3D)

ตอนนี้เราได้สร้างอาร์เรย์ 3 มิติที่มีองค์ประกอบ 12 แบบเดียวกับอาร์เรย์ดั้งเดิมแล้ว arr1

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]]]

วิธีการดีบักค่าข้อผิดพลาดระหว่างการปรับรูปร่าง

หากคุณจำไวยากรณ์ได้ การปรับรูปร่างใหม่จะใช้ได้ก็ต่อเมื่อผลคูณของมิติเท่ากับจำนวนองค์ประกอบในอาร์เรย์

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr2D = arr1.reshape(4,4) print("\nReshaped array:") print(arr2D)

ที่นี่คุณกำลังพยายามเปลี่ยนอาร์เรย์ 12 องค์ประกอบเป็นอาร์เรย์ 4 × 4 ที่มี 16 องค์ประกอบ ล่ามแสดงข้อผิดพลาดของค่าดังที่แสดงด้านล่าง

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] ----------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-11-63552bcc8c37> in <module>() 6 7 # Reshape array ----> 8 arr2 = arr1.reshape(4,4) 9 print("\nReshaped array:") 10 print(arr2) ValueError: cannot reshape array of size 12 into shape (4,4)

เพื่อหลีกเลี่ยงข้อผิดพลาดดังกล่าว คุณอาจใช้ -1 เพื่อสรุปรูปร่างของมิติข้อมูลใดมิติหนึ่งโดยอัตโนมัติ โดยอิงจากจำนวนองค์ประกอบทั้งหมด

ตัวอย่างเช่น หากคุณทราบ n – 1 มิติล่วงหน้า คุณสามารถใช้ -1 เพื่ออนุมานมิติที่ n ในอาร์เรย์ที่เปลี่ยนรูปแบบได้

หากคุณมีอาร์เรย์ 24 องค์ประกอบและต้องการเปลี่ยนรูปร่างให้เป็นอาร์เรย์ 3 มิติ สมมติว่าคุณต้องการ 3 แถวและ 4 คอลัมน์ คุณสามารถส่งผ่านค่า -1 ไปตามมิติที่สามได้

 import numpy as np arr1 = np.arange(1,25) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr_res = arr1.reshape(4,3,-1) print("\nReshaped array:") print(arr_res) print(f"Shape of arr_res:{arr_res.shape}")

เมื่อคุณตรวจสอบรูปร่างของอาร์เรย์รูปร่าง คุณจะเห็นว่าอาร์เรย์ที่ปรับรูปร่างใหม่มีรูปร่างเป็น 2 ตามมิติที่สาม

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] Reshaped array: [[[ 1 2] [ 3 4] [ 5 6]] [[ 7 8] [ 9 10] [11 12]] [[13 14] [15 16] [17 18]] [[19 20] [21 22] [23 24]]] Shape of arr_res:(4, 3, 2)

สิ่งนี้มีประโยชน์อย่างยิ่งในการทำให้อาร์เรย์แบนราบ และคุณจะได้เรียนรู้เกี่ยวกับเรื่องนี้ในหัวข้อถัดไป

ใช้ NumPy reshape() เพื่อแผ่อาร์เรย์

มีบางครั้งที่คุณจำเป็นต้องย้อนกลับจากอาร์เรย์ N มิติเป็นอาร์เรย์แบบแบน สมมติว่าคุณต้องการทำให้ภาพแบนราบเป็นเวกเตอร์พิกเซลยาวๆ

ลองโค้ดตัวอย่างง่ายๆ โดยใช้ขั้นตอนต่อไปนี้:

  • สร้างอาร์เรย์รูปภาพระดับสีเทาขนาด 3 x 3 img_arr โดยมีพิกเซลอยู่ในช่วง 0 ถึง 255
  • ถัดไป ให้แบน img_arr นี้และพิมพ์อาร์เรย์ที่แบนแล้วออกมา flat_arr
  • นอกจากนี้ ให้พิมพ์รูปร่างของ img_arr และ flat_arr เพื่อยืนยัน
 img_arr = np.random.randint(0, 255, (3,3)) print(img_arr) print(f"Shape of img_arr: {img_arr.shape}") flat_arr = img_arr.reshape(-1) print(flat_arr) print(f"Shape of flat_arr: {flat_arr.shape}")

นี่คือผลลัพธ์

 [[195 145 77] [ 63 193 223] [215 43 36]] Shape of img_arr: (3, 3) [195 145 77 63 193 223 215 43 36] Shape of flat_arr: (9,)

ในเซลล์โค้ดด้านบน คุณจะเห็นว่า flat_arr เป็นเวกเตอร์ 1 มิติของค่าพิกเซลที่มี 9 องค์ประกอบ

สรุป

ถึงเวลาทบทวนสิ่งที่เราได้เรียนรู้อย่างรวดเร็ว

  • ใช้ np.reshape(arr, newshape) เพื่อปรับรูปร่าง arr เป็นรูปร่างที่ระบุใน newshape newshape เป็น tuple ที่ระบุขนาดของอาร์เรย์ที่เปลี่ยนรูปแบบใหม่
  • อีกวิธีหนึ่ง ใช้ arr.reshape(d0, d1, …, dn) เพื่อปรับรูปร่าง arr ให้มีรูปร่าง d0 x d1 x … x dn
  • ตรวจสอบว่า d0 * d1 * …* dn = N จำนวนองค์ประกอบในอาร์เรย์ดั้งเดิม เพื่อหลีกเลี่ยงข้อผิดพลาดของค่าในระหว่างการปรับรูปร่างใหม่
  • ใช้ -1 สำหรับมิติข้อมูลไม่เกินหนึ่งรายการในรูปร่างใหม่ หากคุณต้องการให้มิติข้อมูลได้รับการอนุมานโดยอัตโนมัติ
  • สุดท้าย คุณอาจใช้ arr.reshape(-1) เพื่อทำให้อาร์เรย์เรียบ

ตอนนี้คุณรู้วิธีใช้ NumPy reshape() แล้ว เรียนรู้วิธีการทำงานของฟังก์ชัน NumPy linspace()

คุณสามารถลองใช้ตัวอย่างโค้ดในสมุดบันทึก Jupyter ได้หากต้องการ หากคุณกำลังมองหาสภาพแวดล้อมการพัฒนาอื่นๆ โปรดดูคำแนะนำเกี่ยวกับทางเลือกของ Jupyter