Vectorization และ Broadcasting ใน Python

เผยแพร่แล้ว: 2020-12-01

Vectorization และ Broadcasting เป็นวิธีที่จะเพิ่มความเร็วในการประมวลผลและเพิ่มประสิทธิภาพการใช้หน่วยความจำในขณะที่ดำเนินการทางคณิตศาสตร์ด้วย Numpy วิธีการเหล่านี้มีความสำคัญอย่างยิ่งในการตรวจสอบให้แน่ใจว่าเวลามีความซับซ้อนลดลง เพื่อไม่ให้อัลกอริธึมต้องเผชิญกับปัญหาคอขวด การดำเนินการที่ปรับให้เหมาะสมนี้จำเป็นสำหรับแอปพลิเคชันที่จะปรับขนาดได้ เราจะพูดถึงเทคนิคทั้งสองนี้และนำตัวอย่างไปใช้

ในตอนท้ายของบทช่วยสอนนี้ คุณจะมีความรู้ดังต่อไปนี้:

  • วิธีจัดการ Vectorization โดย Numpy
  • ความแตกต่างของเวลาที่มีและไม่มี Vectorization
  • การออกอากาศคืออะไร
  • การแพร่ภาพแตกต่างจากการคูณเมทริกซ์ปกติอย่างไร

เวกเตอร์

หลายครั้งที่เราต้องการการดำเนินการทางคณิตศาสตร์ในอาร์เรย์ เช่น การคูณอาร์เรย์ ตอนนี้ วิธีที่ไม่ใช่เวกเตอร์คือทำการคูณองค์ประกอบอย่างชาญฉลาดโดยใช้การวนซ้ำ การนำมันไปปฏิบัติในลักษณะนี้จะส่งผลให้เกิดการดำเนินการคูณแบบเดียวกันหลายครั้ง ซึ่งจะเป็นการสูญเสียทรัพยากรในการคำนวณหากขนาดข้อมูลใหญ่เกินไป เรามาดูกันอย่างรวดเร็ว

วิธีที่ไม่ใช่เวกเตอร์:

นำเข้าแบบสุ่ม

a = [random.randint( 1 , 100 ) สำหรับ _ ใน range( 10000 )]
b = [random.randint( 1 , 100 ) สำหรับ _ ใน range( 10000 )]
%timeit [i*j สำหรับ i, j ใน zip(a,b)]

#ผลลัพธ์:
>> 1000 ลูป ดีที่สุดจาก 3 : 658 µs ต่อลูป

วิธีเวกเตอร์:

นำเข้า numpy เป็น np
a = np.array([random.randint( 1 , 100 ) สำหรับ _ ใน range( 10000 )])
b = np.array([random.randint( 1 , 100 ) สำหรับ _ ใน range( 10000 )])
%timeit a*b

#ผลลัพธ์:
>> 100000 ลูป ดีที่สุดจาก 3 : 7.25 µs ต่อลูป

อย่างที่เราเห็น เวลาที่ผ่านไปนั้นเปลี่ยนจาก 658 ไมโครวินาทีเหลือเพียง 7.25 ไมโครวินาที นี่เป็นเพราะเมื่อเราพูดว่า a = np.array([]) การดำเนินการทั้งหมดจะได้รับการจัดการภายในโดย numpy และเมื่อเราทำ a*b นั้น numpy จะคูณอาร์เรย์ทั้งหมดภายในคราวเดียวโดยใช้ vectorization

ที่นี่เราใช้คำสั่งมายากล %timeit เพื่อจับเวลาการดำเนินการของกระบวนการซึ่งอาจแตกต่างออกไปในเครื่องของคุณ

ลองดูอีกตัวอย่างหนึ่งของผลิตภัณฑ์ภายนอกของเวกเตอร์ 2 ตัวที่มีขนาด (nx1) และ (1xm) ผลลัพธ์จะเป็น (nxm)

เวลา นำเข้า
นำเข้า numpy
นำเข้า อาร์เรย์
a = array.array( 'i' , [random.randint( 1 , 100 ) สำหรับ _ ใน ช่วง ( 100 )])
b = array.array( 'i' , [random.randint( 1 , 100 ) สำหรับ _ ใน ช่วง ( 100 )])

T1 = time.process_time()
c = numpy.zeros(( 200 , 200 ))

สำหรับ ฉัน อยู่ใน ช่วง (len (a)):
สำหรับ j ใน ช่วง (len (b)):
c[i][j]= a[i]*b[j]

T2 = time.process_time()

พิมพ์ ( f”เวลาในการคำนวณ = { 1,000 *(T2-T1)} ms” )

#ผลลัพธ์:
>> เวลาในการคำนวณ = 6.819299000000001 ms

เอาล่ะ มาทำกับ Numpy กัน

T1 = time.process_time()
c = numpy.outer (a, b)
T2 = time.process_time()

พิมพ์ ( f”เวลาในการคำนวณ = { 1,000 *(T2-T1)} ms” )

#ผลลัพธ์:
>> เวลาในการคำนวณ = 0.2256630000001536 ms

ดังที่เราเห็นอีกครั้ง Numpy ประมวลผลการดำเนินการแบบเดียวกันเร็วขึ้นด้วย vectorization

ต้องอ่าน: แอปพลิเคชั่น Python ที่น่าสนใจในโลกแห่งความจริง

ออกอากาศ

จนถึงตอนนี้ เราได้เห็นตัวอย่างที่ใช้อาร์เรย์ที่มีขนาดเท่ากัน จะเกิดอะไรขึ้นถ้าขนาดของอาร์เรย์ต่างกัน? นี่คือจุดที่ Numpy เป็นอีกหนึ่งฟีเจอร์ที่ยอดเยี่ยมอย่าง Broadcasting ที่ปรากฎขึ้น

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

a = np.array([ 1 , 1 , 1 , 1 ])
a+ 5

#ผลลัพธ์:
อาร์เรย์([ 6 , 6 , 6 , 6 ))

อย่างที่เราเห็น สเกลาร์ 5 ถูกเพิ่มเข้าไปในองค์ประกอบทั้งหมด แล้วมันเกิดขึ้นได้อย่างไร?

ในการจินตนาการถึงกระบวนการ คุณอาจคิดว่าสเกลาร์ 5 ซ้ำ 4 ครั้งเพื่อสร้างอาร์เรย์ที่เพิ่มเข้าไปในอาร์เรย์ a แต่โปรดทราบว่า Numpy ไม่ได้สร้างอาร์เรย์ดังกล่าวซึ่งจะใช้หน่วยความจำเท่านั้น Numpy เพียง "ออกอากาศ" หรือทำซ้ำสเกลาร์ 5 ถึง 4 แห่งเพื่อเพิ่มลงในอาร์เรย์ a

ลองมาอีกตัวอย่างง่ายๆ

a = np.ones(( 3 , 3 ))
b = np.ones( 3 )
a+b

#ผลลัพธ์:
>> อาร์เรย์ ([[ 2. , 2. , 2. ],
[ 2. , 2. , 2. ],
[ 2. , 2. , 2. ]])

ในตัวอย่างข้างต้น อาร์เรย์ของรูปร่าง (3,1) ได้รับการถ่ายทอดไปยัง (3,3) เพื่อให้ตรงกับอาร์เรย์ a

แต่นี่หมายความว่าอาร์เรย์ใดๆ ที่มีมิติใดๆ สามารถออกอากาศเพื่อให้ตรงกับอาร์เรย์ที่มีมิติใดๆ ได้หรือไม่

ไม่!

กฎการออกอากาศ

Numpy ปฏิบัติตามกฎง่ายๆ เพื่อให้แน่ใจว่ามีการออกอากาศเฉพาะอาร์เรย์ที่เป็นไปตามเกณฑ์เท่านั้น ลองมาดูกัน

กฎของการแพร่ภาพกล่าวว่าอาร์เรย์ 2 ตัวที่จะใช้งานต้องมีมิติเท่ากันหรือถ้าตัวใดตัวหนึ่งเป็น 1

ลองดูสิ่งนี้ในการดำเนินการ

ตัวอย่างที่ 1:

พิจารณาอาร์เรย์ของมิติด้านล่าง:

a = 3 x 4 x 7

b = 3 x 4 x 1

มิติสุดท้ายของ b นี้จะถูกถ่ายทอดเพื่อให้ตรงกับขนาด a ถึง 7

ดังนั้น ผลลัพธ์ = 3 x 4 x 7

ตัวอย่างที่ 2:

a = 3 x 4 x 7

ข = 4

ทีนี้ จำนวนมิติของ a และ b ไม่เท่ากัน ในกรณีเช่นนี้ อาร์เรย์ที่มีจำนวนมิติน้อยกว่าจะถูกบุด้วย 1

ดังนั้น ในที่นี้ มิติแรกและอันสุดท้ายของ b คือ 1 ดังนั้นมิติข้อมูลเหล่านี้จึงจะถูกถ่ายทอดให้ตรงกับมิติของ a ถึง 3 และ 7

ดังนั้น ผลลัพธ์ = 3 x 4 x 7

อ่าน: Python Tutorial

ตัวอย่างที่ 3:

a = 3 x 4 x 1 x 5

b = 3 x 1 x 7 x 1

ในที่นี้ อีกครั้ง มิติที่สองและสุดท้ายของ b จะถูกถ่ายทอดเพื่อให้ตรงกับมิติของ a ถึง 4 และ 5 นอกจากนี้ มิติที่สามของ a จะถูกถ่ายทอดเพื่อให้ตรงกับมิติของ b ถึง 7

ดังนั้น ผลลัพธ์ = 3 x 4 x 7 x 5

ทีนี้มาดูว่าเมื่อเงื่อนไขล้มเหลว:

ตัวอย่างที่ 4:

a = 3 x 4 x 7 x 5

b = 3 x 3 x 7 x 4

ในที่นี้ มิติข้อมูลที่สองและสี่ของ b ไม่ตรงกับ a และไม่ใช่ 1 ในกรณีนี้ Python จะส่งค่าผิดพลาด:

ValueError: ไม่ สามารถออกอากาศตัวถูกดำเนินการร่วม กับ รูปร่างได้ ( 3 , 4 , 7 , 5 ) ( 3 , 3 , 7 , 4 )

ตัวอย่างที่ 5:

a = 3 x 4 x 1 x 5

ข = 3 x 2 x 3

ผลลัพธ์: ValueError

ในที่นี้เช่นกัน มิติที่ 2 ไม่ตรงกันและไม่ใช่ 1 สำหรับมิติข้อมูลใดมิติหนึ่ง

ก่อนที่คุณจะไป

Vectorization และ Broadcasting ทั้งสองเป็นวิธีที่ Numpy ทำให้การประมวลผลได้รับการปรับให้เหมาะสมและมีประสิทธิภาพมากขึ้น ควรคำนึงถึงแนวคิดเหล่านี้โดยเฉพาะอย่างยิ่งเมื่อต้องจัดการกับเมทริกซ์และอาร์เรย์ n มิติ ซึ่งพบได้ทั่วไปในข้อมูลรูปภาพและ Neural Networks

หากคุณอยากเรียนรู้เกี่ยวกับ python, data science, ลองดู IIIT-B & upGrad's PG Diploma in Data Science ซึ่งสร้างขึ้นสำหรับมืออาชีพด้านการทำงานและเสนอกรณีศึกษาและโครงการมากกว่า 10 รายการ, การประชุมเชิงปฏิบัติการเชิงปฏิบัติ, การให้คำปรึกษากับผู้เชี่ยวชาญในอุตสาหกรรม ตัวต่อตัวกับที่ปรึกษาในอุตสาหกรรม การเรียนรู้มากกว่า 400 ชั่วโมงและความช่วยเหลือด้านงานกับบริษัทชั้นนำ

Vectorization ใน Python คืออะไร?

Numpy เป็นแพ็คเกจ Python ที่มีฟังก์ชันทางคณิตศาสตร์มาตรฐานหลายอย่าง ช่วยให้ดำเนินการได้อย่างรวดเร็วบนอาร์เรย์ของข้อมูลขนาดใหญ่โดยไม่ต้องวนซ้ำ ซึ่งรวมถึง Vectorization Vectorization ใช้เพื่อเร่งโปรแกรม Python โดยไม่ต้องใช้ลูป การใช้วิธีการดังกล่าวสามารถช่วยลดระยะเวลาที่โค้ดใช้ในการดำเนินการได้ มีการดำเนินการต่างๆ ที่ทำกับเวกเตอร์ เช่น dot product ของ vectors หรือที่เรียกว่าผลคูณสเกลาร์ เพราะมันให้ผลลัพธ์เดี่ยว ผลิตภัณฑ์ภายนอก ซึ่งส่งผลให้มีเมทริกซ์กำลังสองของมิติเท่ากับความยาว x ความยาวของ เวกเตอร์ การคูณตามองค์ประกอบ ซึ่งสร้างองค์ประกอบที่มีดัชนีเดียวกัน

Broadcasting ใน Python คืออะไร?

คำว่า Broadcasting หมายถึงวิธีที่ Numpy จัดการอาร์เรย์ที่มีไดเมนชันต่างกันระหว่างการดำเนินการทางคณิตศาสตร์ซึ่งส่งผลให้เกิดข้อจำกัดเฉพาะ อาร์เรย์ที่เล็กกว่าจะออกอากาศผ่านอาร์เรย์ขนาดใหญ่เพื่อให้รูปแบบสอดคล้องกัน การแพร่ภาพทำให้คุณสามารถกำหนดเวคเตอร์การทำงานของอาร์เรย์ได้ ทำให้การวนซ้ำเกิดขึ้นใน C แทนที่จะเป็น Python อย่างที่ Numpy ทำ มันทำสิ่งนี้ให้สำเร็จโดยไม่ต้องสร้างสำเนาข้อมูลที่ไม่จำเป็น ส่งผลให้มีการใช้อัลกอริธึมที่มีประสิทธิภาพ ในบางสถานการณ์ การออกอากาศเป็นความคิดเชิงลบ เนื่องจากส่งผลให้มีการใช้หน่วยความจำอย่างสิ้นเปลือง ซึ่งทำให้การประมวลผลช้าลง

การใช้ NumPy ใน Python คืออะไร?

NumPy หรือ Numerical Python เป็นไลบรารี Python แบบโอเพ่นซอร์สฟรีที่ใช้โดยการวิจัยและวิศวกรรมเกือบทุกสาขา ไลบรารี NumPy ประกอบด้วยโครงสร้างข้อมูลอาร์เรย์หลายมิติและเมทริกซ์ และนำเสนอวิธีการทำงานอย่างมีประสิทธิภาพบนอาร์เรย์ ซึ่งเป็นออบเจ็กต์อาร์เรย์ n มิติที่เป็นเนื้อเดียวกัน ผู้ใช้สามารถใช้ NumPy เพื่อดำเนินการทางคณิตศาสตร์ที่หลากหลายบนอาร์เรย์ ปรับปรุง Python ด้วยโครงสร้างข้อมูลที่แข็งแกร่งซึ่งให้การคำนวณอย่างมีประสิทธิภาพด้วยอาร์เรย์และเมทริกซ์ ตลอดจนไลบรารีขนาดใหญ่ของฟังก์ชันทางคณิตศาสตร์ระดับสูงที่ทำงานกับอาร์เรย์และเมทริกซ์เหล่านี้