Module 12b

N-dimensional Array using NumPy (II)

วันนี้เราจะเรียนรู้ 🔢

  1. การเข้าถึงข้อมูล (index / slice / เงื่อนไข)
  2. View และ Copy
  3. การประมวลผลแบบ Matrix (@, .T, np.linalg)
x = np.array([[5,6,7,8],
              [9,10,11,12],
              [13,14,15,16]])
print(x[::2, 2:])
[[ 7  8]
 [15 16]]

Note

ต่อจาก Module 12a — การสร้าง array & การคำนวณ · Live Code ใช้ NumPy จริงใน browser (Pyodide) — กด Run

การเข้าถึงข้อมูลใน array 🎯

index · slice · การเลือกด้วยเงื่อนไข

Index และ Slice (1 มิติ)

เข้าถึงข้อมูลด้วย array[index] และ slice ด้วย array[start:stop:step] (เหมือน List)

x = np.array([5,6,7,8,9,10])
print(x[0])
print(x[1:3])
print(x[2:])
print(x[1:5:2])
print(x[::2])
print(x[::-1])   # reverse
5
[6 7]
[ 7  8  9 10]
[6 8]
[5 7 9]
[10  9  8  7  6  5]
# กำหนดค่าใหม่ผ่าน index/slice
x = np.array([5,6,7,8,9,10])
x[1] = 1
print(x)
x[2:] = 0
print(x)
[ 5  1  7  8  9 10]
[5 1 0 0 0 0]

Note

Index array หลายมิติ

array หลายมิติระบุ index แต่ละมิติได้ — x[1,2] หรือ x[1][2]

x = np.array([[5,6,7],[8,9,10]])
print(x[1,2])
print(x[1][2])
10
10

Slice 2 มิติ — x[::2, 2:]

x = np.array([[ 5, 6, 7, 8],
              [ 9,10,11,12],
              [13,14,15,16]])
print(x[::2, 2:])
[[ 7  8]
 [15 16]]
0123 012 5 6 7 8 9 10 11 12 13 14 15 16 x[::2, 2:] → แถว 0,2 · คอลัมน์ 2,3 ได้ [[7, 8], [15, 16]]

Slice 2 มิติ — row / column

print(x[:, 2:])   # ทุก row, column 2 เป็นต้นไป
print(x[2:, :])   # row 2 เป็นต้นไป, ทุก column
[[ 7  8]
 [11 12]
 [15 16]]

[[13 14 15 16]]
0123 012 5 6 7 8 9 10 11 12 13 14 15 16 x[:, 2:] (คอลัมน์ 2+) x[2:, :] (แถว 2+) อยู่ในทั้งสอง slice

Slice 2 มิติ — กำหนดค่า

x = np.array([[ 5, 6, 7, 8],
              [ 9,10,11,12],
              [13,14,15,16]])
x[:, 2:] = 0
print(x)
[[ 5  6  0  0]
 [ 9 10  0  0]
 [13 14  0  0]]
0123 012 5 6 0 0 9 10 0 0 13 14 0 0 x[:, 2:] = 0 กำหนดคอลัมน์ 2,3 = 0 ทุกแถว

เลือกข้อมูลด้วยเงื่อนไข

2 ขั้นตอน: (1) สร้าง selector array ด้วย comparison operator (ได้ array ของ True/False) — (2) นำไปใช้เป็น index

x = np.array([[ 5, 6, 7, 8],
              [ 9,10,11,12],
              [13,14,15,16]])
y = (x > 10)      # selector array
print(y)
[[False False False False]
 [False False  True  True]
 [ True  True  True  True]]

Note

ใช้ selector array เลือก/แก้ข้อมูล

ใช้รูปแบบ array[selector_array] เลือกเฉพาะ item ที่ตรงเงื่อนไข (ผลลัพธ์เป็น 1D array)

print(x[y])           # item ที่ > 10
print(type(x[y]))
[11 12 13 14 15 16]
<class 'numpy.ndarray'>
x[y] = 100   # แก้เฉพาะที่ตรงเงื่อนไข
print(x)
[[  5   6   7   8]
 [  9  10 100 100]
 [100 100 100 100]]

selector array — ตัวอย่างเพิ่มเติม

x2 = np.array([[1,2,3],[11,22,33],
               [10,20,30],[100,200,300]])
y = (x2 <= 10)       # selector

print(x2[y])
print(np.sum(x2[y]))    # ผลรวม
print(np.mean(x2[y]))   # ค่าเฉลี่ย
print(x2[y] * 3)        # คูณเฉพาะที่เลือก
[ 1  2  3 10]
16
4.0
[ 3  6  9 30]

เลือก row ตามเงื่อนไขของ column

โจทย์: row ใดที่ column แรก == 1 ให้หาผลรวมของ column ที่ 2 และ 4

x = np.array([[1,10,1,3,5],
              [1,15,2,3,5],
              [0,20,3,3,5],
              [1,25,4,3,5]])

row_selector = (x[:,0] == 1)      # [ True  True False  True]
sub_x = x[:, [2,4]]               # เลือก column 2 และ 4

total = np.sum(sub_x[row_selector, :], axis=0)
print(total)
[ 7 15]

View และ Copy 🔗

การ slice สร้าง View — แก้ View กระทบต้นฉบับ

View

การเลือกข้อมูลด้วย index / slice คือการสร้าง View — แก้ค่า View แล้ว array ต้นทางเปลี่ยนตาม

x = np.ones((3,3))
y = x[:2, :2]     # สร้าง view จากการ slice

x[0,0] = 0        # แก้ต้นทาง
print(x)
print(y)          # view เปลี่ยนตาม
[[0. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
[[0. 1.]
 [1. 1.]]

Copy

ใช้ .copy() สร้างสำเนาที่แยกออกจากต้นทางเด็ดขาด

x = np.ones((3,3))
y = x[:2, :2].copy()   # copy ใหม่

x[0,0] = 0             # แก้ต้นทาง
print(x)
print(y)               # copy ไม่เปลี่ยน
[[0. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
[[1. 1.]
 [1. 1.]]

การคำนวณ Matrix 🧮

Matrix multiplication · Transpose · Linear Algebra

Matrix Multiplication

ใช้ @ operator หรือ .dot() สำหรับการคูณแบบเมตริกซ์ (Python 3.5+) — shape ต้องสอดคล้องกัน

( m × n ) @ ( n × p ) = ( m × p ) inner ต้องเท่ากัน ✓ shape ผลลัพธ์ เช่น (2×2) @ (2×2) = (2×2) · C[i][j] = แถว i ของ A · คอลัมน์ j ของ B
x = np.array([[1,2],[3,4]])
y = np.array([[1,1],[1,1]])

print(x * y)      # item-wise
print(x @ y)      # matrix mult
print(np.dot(x,y))
[[1 2]
 [3 4]]
[[3 3]
 [7 7]]
[[3 3]
 [7 7]]

Matrix Transposition

ทำ Transpose ด้วย property .T

x = np.array([[1,2,3],[4,5,6]])
print(x, x.shape)
y = x.T
print(y, y.shape)
[[1 2 3]
 [4 5 6]] (2, 3)
[[1 4]
 [2 5]
 [3 6]] (3, 2)

Warning

Transpose ของ 1D-array ได้ 1D-array เหมือนเดิม

x = np.array([1,2,3])
print(x.T, x.T.shape)   # (3,)

Warning

ผลของ Transpose เป็น View — แก้แล้วกระทบต้นทาง

Linear Algebra Module

โมดูลย่อย np.linalg สำหรับพีชคณิตเชิงเส้น เช่น np.linalg.det(), np.linalg.inv(), np.linalg.solve()

x = np.array([[1,2],[3,4]])
print(np.linalg.det(x))   # determinant
print(np.linalg.inv(x))   # inverse
-2.0000000000000004

[[-2.   1. ]
 [ 1.5 -0.5]]

การแก้สมการหลายตัวแปร

แปลงระบบสมการเป็นรูปเมตริกซ์ \(Ax = b\) แล้วแก้ด้วย np.linalg.solve()

1·x₁ + 2·x₂ = 5 3·x₁ + 4·x₂ = 6 1234 x₁x₂ = 56 A x b A x = b
A = np.array([[1,2],[3,4]])   # 2D array
b = np.array([5,6])           # 1D array

x = np.linalg.solve(A, b)     # แก้สมการ
print(x)

x = np.linalg.inv(A) @ b      # หรือ A⁻¹ @ b
print(x)
[-4.   4.5]
[-4.   4.5]

Summary 🎯

สรุป Module 12b 🎉

เข้าถึงข้อมูล

  • array[index] · array[start:stop:step]
  • หลายมิติ: x[i, j] · slice: x[::2, 2:]
  • เงื่อนไข: selector arrayx[x>10]
  • View (slice) vs Copy (.copy())

Matrix

  • @ / .dot() — matrix multiplication
  • .T — transpose (ผลเป็น View)
  • np.linalgdet() inv() solve()

Tip

NumPy = เร็ว + โค้ดสั้น + ใกล้เคียงคณิตศาสตร์