3 วิธีในการคูณเมทริกซ์ใน Python
เผยแพร่แล้ว: 2022-05-09ในบทช่วยสอนนี้ คุณจะได้เรียนรู้วิธี คูณเมทริกซ์สองตัว ใน Python
คุณจะเริ่มต้นด้วยการเรียนรู้เงื่อนไขสำหรับการคูณเมทริกซ์ที่ถูกต้องและเขียนฟังก์ชัน Python ที่กำหนดเองเพื่อคูณเมทริกซ์ ถัดไป คุณจะเห็นว่าคุณสามารถบรรลุผลลัพธ์เดียวกันได้อย่างไรโดยใช้ความเข้าใจรายการที่ซ้อนกัน
สุดท้าย คุณจะต้องใช้ NumPy และฟังก์ชันในตัวเพื่อทำการคูณเมทริกซ์อย่างมีประสิทธิภาพมากขึ้น
วิธีตรวจสอบว่าการคูณเมทริกซ์ถูกต้องหรือไม่
ก่อนเขียนโค้ด Python สำหรับการคูณเมทริกซ์ เรามาทบทวนพื้นฐานของการคูณเมทริกซ์กันก่อน
การคูณเมทริกซ์ระหว่างเมทริกซ์สองตัว A และ B จะใช้ได้ก็ต่อเมื่อ จำนวนคอลัมน์ ในเมทริกซ์ A เท่ากับ จำนวนแถว ในเมทริกซ์ B
คุณน่าจะเคยเจอเงื่อนไขนี้สำหรับการคูณเมทริกซ์มาก่อน อย่างไรก็ตาม คุณเคยสงสัยหรือไม่ว่าเหตุใดจึงเป็นเช่นนี้
นั่นเป็นเพราะวิธีการทำงานของการคูณเมทริกซ์ ลองดูที่ภาพด้านล่าง
ในตัวอย่างทั่วไปของเรา เมทริกซ์ A มี m แถวและ n คอลัมน์ และเมทริกซ์ B มี n แถวและ p คอลัมน์

รูปร่างของผลิตภัณฑ์เมทริกซ์คืออะไร?
องค์ประกอบที่ดัชนี (i, j) ในเมทริกซ์ผลลัพธ์ C คือผลคูณดอทของแถว i ของเมทริกซ์ A และคอลัมน์ j ของเมทริกซ์ B
ดังนั้นเพื่อให้ได้องค์ประกอบที่ดัชนีเฉพาะในเมทริกซ์ผลลัพธ์ C คุณจะต้องคำนวณผลคูณดอทของแถวและคอลัมน์ที่สอดคล้องกันในเมทริกซ์ A และ B ตามลำดับ
ทำซ้ำขั้นตอนข้างต้น คุณจะได้เมทริกซ์ผลิตภัณฑ์ C ของรูปร่าง mxp —พร้อม m แถวและ p คอลัมน์ดังที่แสดงด้านล่าง

และผลคูณดอทหรือผลคูณภายในระหว่างเวกเตอร์สองตัว a และ b ถูกกำหนดโดยสมการต่อไปนี้

มาสรุปกันตอนนี้:
- เห็นได้ชัดว่าดอทโปรดัคถูกกำหนดระหว่างเวกเตอร์ที่มีความยาวเท่ากันเท่านั้น
- ดังนั้น เพื่อให้ผลคูณดอทระหว่างแถวกับคอลัมน์ถูกต้อง—เมื่อคูณเมทริกซ์สองตัว—คุณต้องการให้ทั้งคู่มีจำนวนองค์ประกอบเท่ากัน
- ในตัวอย่างทั่วไปข้างต้น ทุกแถวในเมทริกซ์ A มีองค์ประกอบ n ตัว และทุกคอลัมน์ในเมทริกซ์ B มีองค์ประกอบ n ตัวเช่นกัน
หากคุณพิจารณาให้ละเอียดยิ่งขึ้น n คือจำนวนคอลัมน์ในเมทริกซ์ A และมันคือจำนวนแถวในเมทริกซ์ B ด้วย และนี่คือเหตุผลว่าทำไมคุณถึงต้องการ จำนวนคอลัมน์ ในเมทริกซ์ A เท่ากับ จำนวน ของแถว ในเมทริกซ์ B
ฉันหวังว่าคุณจะเข้าใจเงื่อนไขของการคูณเมทริกซ์ที่ถูกต้องและวิธีรับแต่ละองค์ประกอบในเมทริกซ์ผลิตภัณฑ์
มาเริ่มเขียนโค้ด Python เพื่อคูณเมทริกซ์สองตัวกัน
เขียนฟังก์ชัน Python แบบกำหนดเองเพื่อคูณเมทริกซ์
ในขั้นแรก ให้เราเขียนฟังก์ชันแบบกำหนดเองเพื่อคูณเมทริกซ์
ฟังก์ชันนี้ควรทำสิ่งต่อไปนี้:
- ยอมรับเมทริกซ์สองตัวคือ A และ B เป็นอินพุต
- ตรวจสอบว่าการคูณเมทริกซ์ระหว่าง A และ B ถูกต้องหรือไม่
- ถ้าถูกต้อง ให้คูณเมทริกซ์ A และ B สองตัว แล้วส่งคืนเมทริกซ์ผลิตภัณฑ์ C
- มิฉะนั้น ให้ส่งคืนข้อความแสดงข้อผิดพลาดที่เมทริกซ์ A และ B ไม่สามารถคูณได้
ขั้นตอนที่ 1 : สร้างเมทริกซ์จำนวนเต็มสองเมทริกซ์โดยใช้ฟังก์ชัน random.randint()
ของ NumPy คุณยังสามารถประกาศเมทริกซ์เป็นรายการ Python ที่ซ้อนกันได้
import numpy as np np.random.seed(27) A = np.random.randint(1,10,size = (3,3)) B = np.random.randint(1,10,size = (3,2)) print(f"Matrix A:\n {A}\n") print(f"Matrix B:\n {B}\n") # Output Matrix A: [[4 9 9] [9 1 6] [9 2 3]] Matrix B: [[2 2] [5 7] [4 4]]
ขั้นตอนที่ 2: ไปข้างหน้าและกำหนดฟังก์ชัน multiply_matrix(A,B)
ฟังก์ชันนี้ใช้เมทริกซ์ A
และ B
สองตัวเป็นอินพุต และส่งกลับเมทริกซ์ผลิตภัณฑ์ C
หากการคูณเมทริกซ์ถูกต้อง
def multiply_matrix(A,B): global C if A.shape[1] == B.shape[0]: C = np.zeros((A.shape[0],B.shape[1]),dtype = int) for row in range(rows): for col in range(cols): for elt in range(len(B)): C[row, col] += A[row, elt] * B[elt, col] return C else: return "Sorry, cannot multiply A and B."
การแยกวิเคราะห์นิยามฟังก์ชัน
มาดำเนินการแยกวิเคราะห์นิยามฟังก์ชันกัน
ประกาศ C เป็นตัวแปรส่วนกลาง : โดยค่าเริ่มต้น ตัวแปรทั้งหมดภายในฟังก์ชัน Python มี ขอบเขต ภายใน และคุณไม่สามารถเข้าถึงได้จากภายนอกฟังก์ชัน เพื่อให้ผลิตภัณฑ์เมทริกซ์ C สามารถเข้าถึงได้จากภายนอก เราจะต้องประกาศเป็นตัวแปรส่วนกลาง เพียงเพิ่ม global
qualifier ก่อนชื่อตัวแปร
ตรวจสอบว่าการคูณเมทริกซ์ถูกต้องหรือไม่: ใช้แอตทริบิวต์ shape
เพื่อตรวจสอบว่าสามารถคูณ A และ B ได้หรือไม่ สำหรับอาร์เรย์ arr
ใดๆ arr.shape[0]
และ arr.shape[1]
ให้จำนวน แถว และ คอลัมน์ ตามลำดับ ดังนั้น if A.shape[1] == B.shape[0]
ตรวจสอบว่าการคูณเมทริกซ์นั้นถูกต้องหรือไม่ เฉพาะในกรณีที่เงื่อนไขนี้เป็น True
เมทริกซ์ผลิตภัณฑ์จะถูกคำนวณ มิฉะนั้น ฟังก์ชันจะส่งคืนข้อความแสดงข้อผิดพลาด
ใช้การวนซ้ำแบบซ้อนเพื่อคำนวณค่า: ในการคำนวณองค์ประกอบของเมทริกซ์ผลลัพธ์ เราต้องวนซ้ำผ่านแถวของเมทริกซ์ A และวงรอบนอก for
สิ่งนี้ inner for
loop ช่วยให้เราวนซ้ำคอลัมน์ของเมทริกซ์ B และวงในสุด for
ลูปช่วยเข้าถึงแต่ละองค์ประกอบในคอลัมน์ที่เลือก
️ ตอนนี้เราได้เรียนรู้วิธีการทำงานของฟังก์ชัน Python ในการคูณเมทริกซ์แล้ว มาเรียกใช้ฟังก์ชันด้วยเมทริกซ์ A และ B ที่เราสร้างขึ้นก่อนหน้านี้กัน
multiply_matrix(A,B) # Output array([[ 89, 107], [ 47, 49], [ 40, 44]])
เนื่องจากการคูณเมทริกซ์ระหว่าง A และ B นั้นถูกต้อง ฟังก์ชัน multiply_matrix()
จะส่งกลับเมทริกซ์ผลิตภัณฑ์ C
ใช้ Python Nested List Comprehension เพื่อคูณเมทริกซ์
ในส่วนที่แล้ว คุณเขียนฟังก์ชัน Python เพื่อคูณเมทริกซ์ ตอนนี้ คุณจะเห็นว่าคุณสามารถใช้ความเข้าใจรายการที่ซ้อนกันเพื่อทำเช่นเดียวกันได้อย่างไร
นี่คือความเข้าใจรายการที่ซ้อนกันเพื่อคูณเมทริกซ์

ในตอนแรกอาจดูซับซ้อน แต่เราจะแยกวิเคราะห์ความเข้าใจรายการที่ซ้อนกันทีละขั้นตอน

มาเน้นที่ความเข้าใจทีละรายการและระบุสิ่งที่ทำ
เราจะใช้เทมเพลตทั่วไปต่อไปนี้สำหรับการทำความเข้าใจรายการ:
[<do-this> for <item> in <iterable>] where, <do-this>: what you'd like to do—expression or operation <item>: each item you'd like to perform the operation on <iterable>: the iterable (list, tuple, etc.) that you're looping through
️ ดูคู่มือ List Comprehension ใน Python – พร้อมตัวอย่างเพื่อทำความเข้าใจในเชิงลึก
ก่อนดำเนินการต่อ โปรดทราบว่าเราต้องการสร้างเมทริกซ์ผลลัพธ์ C ทีละแถว
อธิบายความเข้าใจรายการที่ซ้อนกัน
ขั้นตอนที่ 1: คำนวณค่าเดียวในเมทริกซ์ C
กำหนดแถว i ของเมทริกซ์ A และคอลัมน์ j ของเมทริกซ์ B นิพจน์ด้านล่างให้รายการที่ดัชนี (i, j) ในเมทริกซ์ C
sum(a*b for a,b in zip(A_row, B_col) # zip(A_row, B_col) returns an iterator of tuples # If A_row = [a1, a2, a3] & B_col = [b1, b2, b3] # zip(A_row, B_col) returns (a1, b1), (a2, b2), and so on
ถ้า i = j = 1
นิพจน์จะส่งกลับรายการ c_11
ของเมทริกซ์ C ดังนั้นคุณสามารถรับหนึ่งองค์ประกอบในแถวเดียวด้วยวิธีนี้
ขั้นตอนที่ 2: สร้างหนึ่งแถวในเมทริกซ์ C
เป้าหมายต่อไปของเราคือการสร้างแถวทั้งหมด
สำหรับแถวที่ 1 ในเมทริกซ์ A คุณต้องวนซ้ำคอลัมน์ทั้งหมดในเมทริกซ์ B เพื่อให้ได้แถวที่สมบูรณ์หนึ่งแถวในเมทริกซ์ C
กลับไปที่เทมเพลตความเข้าใจรายการ
- แทนที่
<do-this>
ด้วยนิพจน์จากขั้นตอนที่ 1 เพราะนั่นคือสิ่งที่คุณต้องการทำ - ถัดไป แทนที่
<item>
ด้วยB_col
—แต่ละคอลัมน์ในเมทริกซ์ B - สุดท้าย แทนที่
<iterable>
ด้วยzip(*B)
— รายการที่มีคอลัมน์ทั้งหมดในเมทริกซ์ B
และนี่คือความเข้าใจรายการแรก
[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] # zip(*B): * is the unzipping operator # zip(*B) returns a list of columns in matrix B
ขั้นตอนที่ 3: สร้างแถวทั้งหมดและรับเมทริกซ์ C
ถัดไป คุณจะต้องเติมเมทริกซ์ผลิตภัณฑ์ C โดยคำนวณส่วนที่เหลือของแถว
และสำหรับสิ่งนี้ คุณต้องวนซ้ำทุกแถวในเมทริกซ์ A
กลับไปที่รายการความเข้าใจอีกครั้ง และทำดังต่อไปนี้
- แทนที่
<do-this>
ด้วย list comprehension จากขั้นตอนที่ 2 จำได้ว่าเราคำนวณทั้งแถวในขั้นตอนก่อนหน้า - ตอนนี้ แทนที่
<item>
ด้วยA_row
—ทุกแถวในเมทริกซ์ A - และ
<iterable>
ของคุณคือเมทริกซ์ A ขณะที่คุณวนซ้ำแถวของมัน
และนี่คือความเข้าใจรายการซ้อนสุดท้ายของเรา
[[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] for A_row in A]
ได้เวลาตรวจสอบผลแล้ว!
# cast into NumPy array using np.array() C = np.array([[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] for A_row in A]) # Output: [[ 89 107] [ 47 49] [ 40 44]]
หากคุณพิจารณาให้ละเอียดยิ่งขึ้น สิ่งนี้จะเทียบเท่ากับลูปที่ซ้อนกันที่เรามีก่อนหน้านี้—เพียงว่ามันกระชับกว่า
คุณยังสามารถทำสิ่งนี้ทั้งหมดได้อย่างมีประสิทธิภาพมากขึ้นโดยใช้ฟังก์ชันในตัว มาเรียนรู้เกี่ยวกับพวกเขาในหัวข้อถัดไป
ใช้ NumPy matmul() เพื่อคูณเมทริกซ์ใน Python
np.matmul()
รับเมทริกซ์สองตัวเป็นอินพุตและส่งคืนผลิตภัณฑ์หากการคูณเมทริกซ์ระหว่างเมทริกซ์อินพุต ถูกต้อง
C = np.matmul(A,B) print(C) # Output: [[ 89 107] [ 47 49] [ 40 44]]
สังเกตว่าวิธีนี้ง่ายกว่าสองวิธีที่เราเรียนรู้ก่อนหน้านี้อย่างไร ที่จริงแล้ว แทนที่จะใช้ np.matmul()
คุณสามารถใช้ตัวดำเนินการ @ ที่เทียบเท่า และเราจะเห็นสิ่งนั้นทันที
วิธีใช้ @ Operator ใน Python เพื่อคูณเมทริกซ์
ใน Python @
เป็นตัวดำเนินการไบนารีที่ใช้สำหรับการคูณเมทริกซ์
มันทำงานบนเมทริกซ์สองตัว และโดยทั่วไปแล้ว อาร์เรย์ NumPy แบบ N และส่งคืนเมทริกซ์ผลิตภัณฑ์
หมายเหตุ: คุณต้องมี Python 3.5 และใหม่กว่าเพื่อใช้ตัวดำเนินการ
@
นี่คือวิธีที่คุณสามารถใช้
C = [email protected] print(C) # Output array([[ 89, 107], [ 47, 49], [ 40, 44]])
โปรดสังเกตว่าเมทริกซ์ผลิตภัณฑ์ C เหมือนกับที่เราได้รับก่อนหน้านี้
คุณสามารถใช้ np.dot() เพื่อคูณเมทริกซ์ได้หรือไม่
หากคุณเคยเจอโค้ดที่ใช้ np.dot()
เพื่อคูณเมทริกซ์สองตัว นี่คือวิธีการทำงาน
C = np.dot(A,B) print(C) # Output: [[ 89 107] [ 47 49] [ 40 44]]
คุณจะเห็นว่า np.dot(A, B)
ส่งคืนเมทริกซ์ผลิตภัณฑ์ที่คาดไว้ด้วย
อย่างไรก็ตาม ตามเอกสาร NumPy คุณควรใช้ np.dot()
เพื่อคำนวณผลคูณดอทของเวกเตอร์หนึ่งมิติสองตัวเท่านั้น ไม่ใช่สำหรับการคูณเมทริกซ์
จากส่วนก่อนหน้านี้ องค์ประกอบที่ดัชนี (i, j) ของผลิตภัณฑ์เมทริกซ์ C คือผลคูณดอทของแถว i ของเมทริกซ์ A และคอลัมน์ j ของเมทริกซ์ B
เนื่องจาก NumPy ถ่ายทอดการทำงานของผลิตภัณฑ์ดอทนี้โดยปริยายไปยังทุกแถวและทุกคอลัมน์ คุณจะได้เมทริกซ์ผลิตภัณฑ์ที่เป็นผลลัพธ์ แต่เพื่อให้โค้ดของคุณอ่านได้และหลีกเลี่ยงความคลุมเครือ ให้ใช้ np.matmul()
หรือตัวดำเนินการ @
แทน
บทสรุป
ในบทช่วยสอนนี้ คุณได้เรียนรู้สิ่งต่อไปนี้
- เงื่อนไขสำหรับการคูณเมทริกซ์ให้ถูกต้อง: จำนวน คอลัมน์ ในเมทริกซ์ A = จำนวน แถว ในเมทริกซ์ B
- วิธีเขียนฟังก์ชัน Python แบบกำหนดเองที่ตรวจสอบว่าการคูณเมทริกซ์นั้นถูกต้องและส่งคืนเมทริกซ์ผลิตภัณฑ์ได้อย่างไร เนื้อหาของฟังก์ชันใช้การซ้อนกันสำหรับลูป
- ต่อไป คุณได้เรียนรู้วิธีใช้ความเข้าใจรายการที่ซ้อนกันเพื่อคูณเมทริกซ์ มีความกระชับมากกว่าการวนซ้ำ แต่มีแนวโน้มที่จะมีปัญหาในการอ่านได้
- ในที่สุด คุณได้เรียนรู้การใช้ฟังก์ชันในตัวของ NumPy np.matmul() เพื่อคูณเมทริกซ์และวิธีนี้มีประสิทธิภาพมากที่สุดในแง่ของความเร็ว
- คุณยังได้เรียนรู้เกี่ยวกับตัวดำเนินการ @ เพื่อคูณเมทริกซ์สองตัวใน Python
และนั่นเป็นการสรุปการสนทนาของเราเกี่ยวกับการคูณเมทริกซ์ใน Python ในขั้นตอนต่อไป เรียนรู้วิธีตรวจสอบว่าตัวเลขเป็นจำนวนเฉพาะใน Python หรือไม่ หรือแก้ปัญหาที่น่าสนใจเกี่ยวกับสตริง Python
มีความสุขในการเรียนรู้!