11: NumPy

11-4: Element-wise Operation

** ถ้าใช้งานบนมือถือหรือ tablet แนะนำให้ใช้ Chrome หรือ Safari เท่านั้น **

แบบฝึกหัด 11-4 ข้อที่ 1

กำหนดให้มีอาเรย์ 2 มิติ A, B, C และ D ให้แล้ว อาเรย์ทั้งสี่มีขนาดเท่ากันหมด จงเขียนคำสั่งเพื่อสร้างอาเรย์ E ที่มีขนาดเท่ากับอาเรย์ทั้งสี่ โดยแต่ละตัว Ei,j มีค่าเท่ากับ (Ai,j + Bi,jCi,j) / Di,j (ไม่ต้องใช้คำสั่งวงวนใด ๆ)

import numpy as np A = np.random.randint(1,10,35).reshape((5,7)) B = np.random.randint(1,10,35).reshape((5,7)) C = np.random.randint(1,10,35).reshape((5,7)) D = np.random.randint(1,10,35).reshape((5,7)) E = (A + B*C)/D import numpy as np Ex().check_not(has_code(r"(for|while)"), msg="ไม่ใช้ for หรือ while นะ") for v in 'ABCDE': obj = Ex().check_object(v, missing_msg = "ไม่มีตัวแปร `" + v + "`") obj.has_equal_value(expr_code = "type("+v+")", incorrect_msg = "`" + v + "` ต้องเป็น numpy array") obj.has_equal_value(expr_code = v+".dtype", incorrect_msg = "`" + v + "` เก็บข้อมูลที่มีประเภทข้อมูลไม่ตรงตามโจทย์") obj.has_equal_value(expr_code = 'np.round('+v+', 7)', incorrect_msg = "`" + v + "` มีค่าไม่ตรงตามโจทย์")
แบบฝึกหัด 11-4 ข้อที่ 2

กำหนดให้มีอาเรย์ A เป็นอาเรย์หนึ่งมิติเก็บจำนวนเต็ม จงสร้างอาเรย์ต่อไปนี้ (โดยไม่ต้องใช้คำสั่งวงวนใด ๆ)

  • B เก็บจำนวนใน A เฉพาะตัวที่มีค่าตั้งแต่ 10 ถึง 20 เท่านั้น (เก็บในลำดับก่อนหลังเช่นเดียวกับใน A)
  • C เก็บจำนวนใน A เฉพาะตัวที่มีค่าหารด้วย 3 หรือ 7 ลงตัวเท่านั้น (เก็บในลำดับก่อนหลังเช่นเดียวกับใน A)

import numpy as np A = np.array([10,20] + np.random.randint(0, 30, 100).tolist()) import numpy as np B = A[(10 <= A) & (A <= 20)] C = A[(A%3 == 0) | (A%7 == 0)] import numpy as np Ex().check_not(has_code(r"(for|while)"), msg="ไม่ใช้ for หรือ while นะ") for v in "BC": obj = Ex().check_object(v, missing_msg = "ไม่มีตัวแปร `" + v + "`") obj.has_equal_value(expr_code = "type("+v+")", incorrect_msg = "`" + v + "` ต้องเป็น numpy array") obj.has_equal_value(expr_code = v+".dtype", incorrect_msg = "`" + v + "` ต้องเก็บจำนวนเต็ม") obj.has_equal_value(incorrect_msg = "`" + v + "` มีค่าไม่ตรงตามโจทย์")
numpy ไม่ให้เขียน 10 <= A <= 20 จึงต้องแยกการเปรียบเทียบเป็นสองกรณี แล้วนำมา "และ" ด้วย & (ระวังด้วยว่า & จะถูกทำก่อนการเปรียบเทียบ จึงต้องใส่วงเล็บกำกับลำดับการทำงานด้วย) สำหรับกรณี "หรือ" ก็เช่นกัน
แบบฝึกหัด 11-4 ข้อที่ 3

Cross product ของเวกเตอร์ a กับ b โดยที่ a = < ax, ay, az > กับ b = < bx, by, bz > คือเวกเตอร์ < aybz − azby, azbx − axbz, axby − aybx > จงเขียนฟังก์ชัน cross_product(A, B) โดยที่ A และ B เป็นอาเรย์ขนาด nx3 แต่ละแถวมีสามช่องแทนส่วนประกอบของเวกเตอรในแนวแกน x, y และ z ตามลำดับ ฟังก์ชันนี้คืนอาเรย์ขนาด nx3 ที่มีแถวที่ k เก็บ cross product ของเวกเตอร์ในแถวที่ k ของ A และ B (ไม่ต้องใช้คำสั่งวงวนใด ๆ ในฟังก์ชัน)

import numpy as np def cross_product(A, B): import numpy as np def cross_product(A, B): Ax = A[:,0]; Ay = A[:,1]; Az = A[:,2] Bx = B[:,0]; By = B[:,1]; Bz = B[:,2] Cx = Ay*Bz - Az*By Cy = Az*Bx - Ax*Bz Cz = Ax*By - Ay*Bx return np.array([Cx, Cy, Cz]).T import numpy as np q = "`" fname = "cross_product" A = 'np.array(' + str([np.random.randint(-10,10,3).tolist() for k in range(5)]) + ')' B = 'np.array(' + str([np.random.randint(-10,10,3).tolist() for k in range(5)]) + ')' func = Ex().check_function_def(fname, missing_msg="ไม่พบฟังก์ชัน " + (q+fname+q)) func.has_equal_part_len('args', 'ฟังก์ชันนี้รับพารามิเตอร์หนึ่งตัว') func.check_not(has_code(r"(for|while)"), msg="ไม่ใช้ for หรือ while นะ") func.check_not(has_code(r"(np|numpy)\s*\.\s*cross\s*\("), msg="ไม่ใช้ฟังก์ชัน numpy.cross นะ ลองเขียนเอง") fcall = fname + "(" + A + "," + B + ")" func.check_call(fcall).has_equal_value(incorrect_msg=(q+fname+q) + " ให้ผลผิด")
แบบฝึกหัด 11-4 ข้อที่ 4

จงเขียนฟังก์ชัน asterisk(A) ที่รับ A ซึ่งเป็นอาเรย์ของจำนวนเต็มขนาด nxn (โดยที่ n เป็นจำนวนคี่) ฟังก์ชันนี้คืนอาเรย์ขนาดเดียวกับ A มีข้อมูลเหมือนใน A เฉพาะในแนวทแยงมุมสองแนว และ แนวตั้งกับแนวนอนตรงกลางอาเรย์ (ดังแสดงในรูปด้วยช่องสีขาว) ส่วนช่องอื่นให้เป็น 0 หมด (ไม่ต้องใช้คำสั่งวงวนใด ๆ ในฟังก์ชัน)

import numpy as np def asterisk(A): import numpy as np def asterisk(A): n = A.shape[0] I = np.identity(n, int) M = I + I[::-1] M[n//2,:] = M[:,n//2] = 1 return A*M import numpy as np q = "`" fname = "asterisk" arg = 'np.array(' + str([[np.random.randint(0,9) for k in range(11)] for j in range(11)]) + ')' func = Ex().check_function_def(fname, missing_msg="ไม่พบฟังก์ชัน " + (q+fname+q)) func.has_equal_part_len('args', 'ฟังก์ชันนี้รับพารามิเตอร์หนึ่งตัว') func.check_not(has_code(r"(for|while)"), msg="ไม่ใช้ for หรือ while นะ") fcall = fname + "(" + arg + ")" func.check_call(fcall).has_equal_value(incorrect_msg=(q+fname+q) + " ให้ผลผิด")