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

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

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

และ NumPy 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() จะพยายามส่งคืนมุมมองทุกครั้งที่ทำได้ มิฉะนั้นจะส่งคืนสำเนา มาพูดถึงความแตกต่างระหว่างมุมมองและสำเนากัน

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

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

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

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

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

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

  การบังคับใช้กฎหมายสามารถติดตามบุคคลด้วยที่อยู่ IP ได้หรือไม่?

ตอนนี้ให้เราใช้ไวยากรณ์ข้างต้น และปรับรูปร่าง 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]]

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

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

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

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

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

อย่างที่คุณเห็น แอตทริบิวต์ฐานของ 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 มิติกัน

  “Unified Memory” เร่งความเร็ว Macs M1 ARM ของ Apple

ใช้ 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)

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

  วิธีตรวจสอบระดับแบตเตอรี่ของ AirPods

ใช้ 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

เรื่องล่าสุด

x