1. NumPy ๊ธฐ์ดˆ

1. NumPy ๊ธฐ์ดˆ

๋‹ค์Œ: NumPy ๊ณ ๊ธ‰

๊ฐœ์š”

NumPy(Numerical Python)๋Š” Python์—์„œ ์ˆ˜์น˜ ๊ณ„์‚ฐ์„ ์œ„ํ•œ ํ•ต์‹ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋‹ค์ฐจ์› ๋ฐฐ์—ด ๊ฐ์ฒด์™€ ๋ฐฐ์—ด ์—ฐ์‚ฐ์„ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.


1. NumPy ๋ฐฐ์—ด ์ƒ์„ฑ

1.1 ๊ธฐ๋ณธ ๋ฐฐ์—ด ์ƒ์„ฑ

import numpy as np

# ๋ฆฌ์ŠคํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐฐ์—ด ์ƒ์„ฑ
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1)  # [1 2 3 4 5]
print(type(arr1))  # <class 'numpy.ndarray'>

# 2์ฐจ์› ๋ฐฐ์—ด
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)
# [[1 2 3]
#  [4 5 6]]

# 3์ฐจ์› ๋ฐฐ์—ด
arr3 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(arr3.shape)  # (2, 2, 2)

1.2 ํŠน์ˆ˜ ๋ฐฐ์—ด ์ƒ์„ฑ

# 0์œผ๋กœ ์ฑ„์›Œ์ง„ ๋ฐฐ์—ด
zeros = np.zeros((3, 4))
print(zeros)

# 1๋กœ ์ฑ„์›Œ์ง„ ๋ฐฐ์—ด
ones = np.ones((2, 3))
print(ones)

# ํŠน์ • ๊ฐ’์œผ๋กœ ์ฑ„์›Œ์ง„ ๋ฐฐ์—ด
full = np.full((2, 2), 7)
print(full)  # [[7 7], [7 7]]

# ๋‹จ์œ„ ํ–‰๋ ฌ
eye = np.eye(3)
print(eye)

# ๋นˆ ๋ฐฐ์—ด (์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์€ ๊ฐ’)
empty = np.empty((2, 3))

1.3 ์ˆœ์ฐจ์  ๋ฐฐ์—ด ์ƒ์„ฑ

# arange: ๋ฒ”์œ„ ์ง€์ •
arr = np.arange(0, 10, 2)  # 0๋ถ€ํ„ฐ 10 ๋ฏธ๋งŒ, 2์”ฉ ์ฆ๊ฐ€
print(arr)  # [0 2 4 6 8]

# linspace: ๋“ฑ๊ฐ„๊ฒฉ ๋ถ„ํ• 
arr = np.linspace(0, 1, 5)  # 0๋ถ€ํ„ฐ 1๊นŒ์ง€ 5๊ฐœ๋กœ ๊ท ๋“ฑ ๋ถ„ํ• 
print(arr)  # [0.   0.25 0.5  0.75 1.  ]

# logspace: ๋กœ๊ทธ ์Šค์ผ€์ผ ๋“ฑ๊ฐ„๊ฒฉ
arr = np.logspace(0, 2, 5)  # 10^0 ๋ถ€ํ„ฐ 10^2 ๊นŒ์ง€
print(arr)  # [  1.    3.16  10.   31.62 100. ]

2. ๋ฐฐ์—ด ์†์„ฑ

arr = np.array([[1, 2, 3], [4, 5, 6]])

# ์ฐจ์› ์ˆ˜
print(arr.ndim)  # 2

# ํ˜•ํƒœ (shape)
print(arr.shape)  # (2, 3)

# ์ „์ฒด ์š”์†Œ ๊ฐœ์ˆ˜
print(arr.size)  # 6

# ๋ฐ์ดํ„ฐ ํƒ€์ž…
print(arr.dtype)  # int64

# ์š”์†Œ๋‹น ๋ฐ”์ดํŠธ ์ˆ˜
print(arr.itemsize)  # 8

# ์ „์ฒด ๋ฐ”์ดํŠธ ์ˆ˜
print(arr.nbytes)  # 48

๋ฐ์ดํ„ฐ ํƒ€์ž… ์ง€์ •

# ์ •์ˆ˜
arr_int = np.array([1, 2, 3], dtype=np.int32)

# ์‹ค์ˆ˜
arr_float = np.array([1, 2, 3], dtype=np.float64)

# ๋ณต์†Œ์ˆ˜
arr_complex = np.array([1, 2, 3], dtype=np.complex128)

# ๋ถˆ๋ฆฌ์–ธ
arr_bool = np.array([0, 1, 0, 1], dtype=np.bool_)

# ํƒ€์ž… ๋ณ€ํ™˜
arr = np.array([1.5, 2.7, 3.9])
arr_int = arr.astype(np.int32)  # [1, 2, 3]

3. ์ธ๋ฑ์‹ฑ๊ณผ ์Šฌ๋ผ์ด์‹ฑ

3.1 ๊ธฐ๋ณธ ์ธ๋ฑ์‹ฑ

arr = np.array([10, 20, 30, 40, 50])

# ๋‹จ์ผ ์š”์†Œ ์ ‘๊ทผ
print(arr[0])   # 10
print(arr[-1])  # 50

# 2์ฐจ์› ๋ฐฐ์—ด
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

print(arr2d[0, 0])  # 1
print(arr2d[1, 2])  # 6
print(arr2d[-1, -1])  # 9

3.2 ์Šฌ๋ผ์ด์‹ฑ

arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

# ๊ธฐ๋ณธ ์Šฌ๋ผ์ด์‹ฑ [start:stop:step]
print(arr[2:7])     # [2 3 4 5 6]
print(arr[::2])     # [0 2 4 6 8]
print(arr[::-1])    # [9 8 7 6 5 4 3 2 1 0]

# 2์ฐจ์› ์Šฌ๋ผ์ด์‹ฑ
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

print(arr2d[0:2, 1:3])
# [[2 3]
#  [5 6]]

print(arr2d[:, 0])  # ์ฒซ ๋ฒˆ์งธ ์—ด: [1 4 7]
print(arr2d[1, :])  # ๋‘ ๋ฒˆ์งธ ํ–‰: [4 5 6]

3.3 ๋ถˆ๋ฆฌ์–ธ ์ธ๋ฑ์‹ฑ

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

# ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์š”์†Œ ์„ ํƒ
mask = arr > 5
print(mask)  # [False False False False False  True  True  True  True  True]
print(arr[mask])  # [ 6  7  8  9 10]

# ์ง์ ‘ ์กฐ๊ฑด ์‚ฌ์šฉ
print(arr[arr > 5])  # [ 6  7  8  9 10]
print(arr[arr % 2 == 0])  # [ 2  4  6  8 10]

# ๋ณตํ•ฉ ์กฐ๊ฑด
print(arr[(arr > 3) & (arr < 8)])  # [4 5 6 7]
print(arr[(arr < 3) | (arr > 8)])  # [ 1  2  9 10]

3.4 ํŒฌ์‹œ ์ธ๋ฑ์‹ฑ

arr = np.array([10, 20, 30, 40, 50])

# ์ธ๋ฑ์Šค ๋ฐฐ์—ด๋กœ ์ ‘๊ทผ
indices = [0, 2, 4]
print(arr[indices])  # [10 30 50]

# 2์ฐจ์› ๋ฐฐ์—ด
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# ํŠน์ • ํ–‰ ์„ ํƒ
print(arr2d[[0, 2]])
# [[1 2 3]
#  [7 8 9]]

# ํŠน์ • ์š”์†Œ ์„ ํƒ
rows = [0, 1, 2]
cols = [0, 1, 2]
print(arr2d[rows, cols])  # [1 5 9] (๋Œ€๊ฐ์„  ์š”์†Œ)

4. ๋ฐฐ์—ด ํ˜•ํƒœ ๋ณ€ํ™˜

4.1 reshape

arr = np.arange(12)
print(arr)  # [ 0  1  2  3  4  5  6  7  8  9 10 11]

# 2์ฐจ์›์œผ๋กœ ๋ณ€ํ™˜
arr2d = arr.reshape(3, 4)
print(arr2d)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

# -1 ์‚ฌ์šฉ: ์ž๋™ ๊ณ„์‚ฐ
arr2d = arr.reshape(4, -1)  # 4ํ–‰, ์—ด ์ž๋™ ๊ณ„์‚ฐ
print(arr2d.shape)  # (4, 3)

arr2d = arr.reshape(-1, 6)  # ํ–‰ ์ž๋™ ๊ณ„์‚ฐ, 6์—ด
print(arr2d.shape)  # (2, 6)

4.2 flatten๊ณผ ravel

arr2d = np.array([[1, 2, 3], [4, 5, 6]])

# flatten: ๋ณต์‚ฌ๋ณธ ์ƒ์„ฑ
flat = arr2d.flatten()
print(flat)  # [1 2 3 4 5 6]

# ravel: ๋ทฐ(view) ์ƒ์„ฑ (์›๋ณธ ๊ณต์œ )
rav = arr2d.ravel()
print(rav)  # [1 2 3 4 5 6]

4.3 ์ „์น˜ (Transpose)

arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape)  # (2, 3)

# ์ „์น˜
transposed = arr.T
print(transposed)
# [[1 4]
#  [2 5]
#  [3 6]]
print(transposed.shape)  # (3, 2)

# ๋‹ค์ฐจ์› ์ „์น˜
arr3d = np.arange(24).reshape(2, 3, 4)
print(arr3d.transpose(1, 0, 2).shape)  # (3, 2, 4)

4.4 ์ฐจ์› ์ถ”๊ฐ€/์ œ๊ฑฐ

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

# ์ฐจ์› ์ถ”๊ฐ€
arr_2d = arr[np.newaxis, :]  # ๋˜๋Š” arr.reshape(1, -1)
print(arr_2d.shape)  # (1, 3)

arr_col = arr[:, np.newaxis]  # ๋˜๋Š” arr.reshape(-1, 1)
print(arr_col.shape)  # (3, 1)

# expand_dims ์‚ฌ์šฉ
arr_exp = np.expand_dims(arr, axis=0)
print(arr_exp.shape)  # (1, 3)

# squeeze: ํฌ๊ธฐ 1์ธ ์ฐจ์› ์ œ๊ฑฐ
arr = np.array([[[1, 2, 3]]])
print(arr.shape)  # (1, 1, 3)
print(np.squeeze(arr).shape)  # (3,)

5. ๋ฐฐ์—ด ์—ฐ์‚ฐ

5.1 ๊ธฐ๋ณธ ์‚ฐ์ˆ  ์—ฐ์‚ฐ

a = np.array([1, 2, 3, 4])
b = np.array([10, 20, 30, 40])

# ์š”์†Œ๋ณ„ ์—ฐ์‚ฐ
print(a + b)   # [11 22 33 44]
print(a - b)   # [ -9 -18 -27 -36]
print(a * b)   # [ 10  40  90 160]
print(a / b)   # [0.1 0.1 0.1 0.1]
print(a ** 2)  # [ 1  4  9 16]
print(a % 2)   # [1 0 1 0]
print(a // 2)  # [0 1 1 2]

# ์Šค์นผ๋ผ ์—ฐ์‚ฐ
print(a + 10)  # [11 12 13 14]
print(a * 2)   # [2 4 6 8]

5.2 ์œ ๋‹ˆ๋ฒ„์„ค ํ•จ์ˆ˜ (ufuncs)

arr = np.array([1, 4, 9, 16, 25])

# ์ˆ˜ํ•™ ํ•จ์ˆ˜
print(np.sqrt(arr))   # [1. 2. 3. 4. 5.]
print(np.exp(arr))    # ์ง€์ˆ˜ ํ•จ์ˆ˜
print(np.log(arr))    # ์ž์—ฐ๋กœ๊ทธ
print(np.log10(arr))  # ์ƒ์šฉ๋กœ๊ทธ

# ์‚ผ๊ฐ ํ•จ์ˆ˜
angles = np.array([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])
print(np.sin(angles))
print(np.cos(angles))
print(np.tan(angles))

# ๋ฐ˜์˜ฌ๋ฆผ
arr = np.array([1.2, 2.5, 3.7, 4.4])
print(np.round(arr))   # [1. 2. 4. 4.]
print(np.floor(arr))   # [1. 2. 3. 4.]
print(np.ceil(arr))    # [2. 3. 4. 5.]
print(np.trunc(arr))   # [1. 2. 3. 4.]

# ์ ˆ๋Œ“๊ฐ’
arr = np.array([-1, -2, 3, -4])
print(np.abs(arr))  # [1 2 3 4]

5.3 ์ง‘๊ณ„ ํ•จ์ˆ˜

arr = np.array([[1, 2, 3], [4, 5, 6]])

# ์ „์ฒด ์ง‘๊ณ„
print(np.sum(arr))    # 21
print(np.mean(arr))   # 3.5
print(np.std(arr))    # 1.707...
print(np.var(arr))    # 2.916...
print(np.min(arr))    # 1
print(np.max(arr))    # 6
print(np.prod(arr))   # 720 (๋ชจ๋“  ์š”์†Œ์˜ ๊ณฑ)

# ์ถ• ๊ธฐ์ค€ ์ง‘๊ณ„
print(np.sum(arr, axis=0))  # ์—ด ํ•ฉ๊ณ„: [5 7 9]
print(np.sum(arr, axis=1))  # ํ–‰ ํ•ฉ๊ณ„: [6 15]

print(np.mean(arr, axis=0))  # ์—ด ํ‰๊ท : [2.5 3.5 4.5]
print(np.mean(arr, axis=1))  # ํ–‰ ํ‰๊ท : [2. 5.]

# ๋ˆ„์  ํ•ฉ/๊ณฑ
print(np.cumsum(arr))  # [ 1  3  6 10 15 21]
print(np.cumprod(arr)) # [  1   2   6  24 120 720]

# ์ธ๋ฑ์Šค ๋ฐ˜ํ™˜
print(np.argmin(arr))  # 0 (์ตœ์†Ÿ๊ฐ’์˜ ์ธ๋ฑ์Šค)
print(np.argmax(arr))  # 5 (์ตœ๋Œ“๊ฐ’์˜ ์ธ๋ฑ์Šค)

6. ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…

๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…์€ ํฌ๊ธฐ๊ฐ€ ๋‹ค๋ฅธ ๋ฐฐ์—ด ๊ฐ„์˜ ์—ฐ์‚ฐ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” NumPy์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

6.1 ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ… ๊ทœ์น™

  1. ๋‘ ๋ฐฐ์—ด์˜ ์ฐจ์› ์ˆ˜๊ฐ€ ๋‹ค๋ฅด๋ฉด, ์ž‘์€ ๋ฐฐ์—ด์˜ shape ์•ž์— 1์„ ์ถ”๊ฐ€
  2. ๊ฐ ์ฐจ์›์—์„œ ํฌ๊ธฐ๊ฐ€ 1์ธ ๋ฐฐ์—ด์€ ๋‹ค๋ฅธ ๋ฐฐ์—ด์˜ ํฌ๊ธฐ์— ๋งž์ถฐ ํ™•์žฅ
  3. ํฌ๊ธฐ๊ฐ€ 1์ด ์•„๋‹ˆ๊ณ  ์„œ๋กœ ๋‹ค๋ฅด๋ฉด ์˜ค๋ฅ˜ ๋ฐœ์ƒ
# ์Šค์นผ๋ผ์™€ ๋ฐฐ์—ด
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr + 10)
# [[11 12 13]
#  [14 15 16]]

# 1์ฐจ์›๊ณผ 2์ฐจ์›
arr = np.array([[1, 2, 3], [4, 5, 6]])
row = np.array([10, 20, 30])
print(arr + row)
# [[11 22 33]
#  [14 25 36]]

# ์—ด ๋ฒกํ„ฐ์™€ 2์ฐจ์›
col = np.array([[100], [200]])
print(arr + col)
# [[101 102 103]
#  [204 205 206]]

6.2 ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ… ์˜ˆ์ œ

# ํ‘œ์ค€ํ™” (standardization)
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
mean = np.mean(data, axis=0)  # [4. 5. 6.]
std = np.std(data, axis=0)    # [2.449 2.449 2.449]
standardized = (data - mean) / std

# ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ
point = np.array([1, 2])
points = np.array([[0, 0], [1, 1], [2, 2], [3, 3]])
distances = np.sqrt(np.sum((points - point) ** 2, axis=1))
print(distances)  # [2.236 1.    1.414 2.236]

7. ๋ฐฐ์—ด ๊ฒฐํ•ฉ๊ณผ ๋ถ„ํ• 

7.1 ๋ฐฐ์—ด ๊ฒฐํ•ฉ

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

# ์ˆ˜์ง ๊ฒฐํ•ฉ (ํ–‰ ๋ฐฉํ–ฅ)
v_stack = np.vstack([a, b])
print(v_stack)
# [[1 2]
#  [3 4]
#  [5 6]
#  [7 8]]

# ์ˆ˜ํ‰ ๊ฒฐํ•ฉ (์—ด ๋ฐฉํ–ฅ)
h_stack = np.hstack([a, b])
print(h_stack)
# [[1 2 5 6]
#  [3 4 7 8]]

# concatenate ์‚ฌ์šฉ
concat_v = np.concatenate([a, b], axis=0)  # vstack๊ณผ ๋™์ผ
concat_h = np.concatenate([a, b], axis=1)  # hstack๊ณผ ๋™์ผ

# ๊นŠ์ด ๋ฐฉํ–ฅ ๊ฒฐํ•ฉ
d_stack = np.dstack([a, b])
print(d_stack.shape)  # (2, 2, 2)

7.2 ๋ฐฐ์—ด ๋ถ„ํ• 

arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

# ์ˆ˜์ง ๋ถ„ํ• 
v_split = np.vsplit(arr, 3)  # 3๊ฐœ๋กœ ๋ถ„ํ• 
print(len(v_split))  # 3

# ์ˆ˜ํ‰ ๋ถ„ํ• 
h_split = np.hsplit(arr, 2)  # 2๊ฐœ๋กœ ๋ถ„ํ• 
print(h_split[0])
# [[ 1  2]
#  [ 5  6]
#  [ 9 10]]

# split ์‚ฌ์šฉ
split_arr = np.split(arr, [1, 2], axis=0)  # ์ธ๋ฑ์Šค 1, 2์—์„œ ๋ถ„ํ• 
print(len(split_arr))  # 3

8. ๋ณต์‚ฌ์™€ ๋ทฐ

8.1 ๋ทฐ (View) - ์–•์€ ๋ณต์‚ฌ

arr = np.array([1, 2, 3, 4, 5])

# ์Šฌ๋ผ์ด์‹ฑ์€ ๋ทฐ๋ฅผ ์ƒ์„ฑ
view = arr[1:4]
view[0] = 100

print(arr)   # [  1 100   3   4   5]  # ์›๋ณธ๋„ ๋ณ€๊ฒฝ๋จ
print(view)  # [100   3   4]

8.2 ๋ณต์‚ฌ (Copy) - ๊นŠ์€ ๋ณต์‚ฌ

arr = np.array([1, 2, 3, 4, 5])

# ๋ช…์‹œ์  ๋ณต์‚ฌ
copy = arr.copy()
copy[0] = 100

print(arr)   # [1 2 3 4 5]  # ์›๋ณธ ์œ ์ง€
print(copy)  # [100 2 3 4 5]

์—ฐ์Šต ๋ฌธ์ œ

๋ฌธ์ œ 1: ๋ฐฐ์—ด ์ƒ์„ฑ

1๋ถ€ํ„ฐ 100๊นŒ์ง€์˜ ์ •์ˆ˜ ์ค‘ 3์˜ ๋ฐฐ์ˆ˜๋งŒ ํฌํ•จํ•˜๋Š” ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜์„ธ์š”.

# ํ’€์ด
arr = np.arange(3, 101, 3)
# ๋˜๋Š”
arr = np.arange(1, 101)
arr = arr[arr % 3 == 0]

๋ฌธ์ œ 2: ํ–‰๋ ฌ ์—ฐ์‚ฐ

3x3 ๋‹จ์œ„ ํ–‰๋ ฌ์˜ ๋Œ€๊ฐ์„  ์š”์†Œ์˜ ํ•ฉ์„ ๊ตฌํ•˜์„ธ์š”.

# ํ’€์ด
eye = np.eye(3)
diagonal_sum = np.trace(eye)  # 3.0
# ๋˜๋Š”
diagonal_sum = np.sum(np.diag(eye))

๋ฌธ์ œ 3: ๋ธŒ๋กœ๋“œ์บ์ŠคํŒ…

4x4 ํ–‰๋ ฌ์—์„œ ๊ฐ ์—ด์˜ ์ตœ๋Œ“๊ฐ’์œผ๋กœ ์ •๊ทœํ™”ํ•˜์„ธ์š” (๊ฐ ์š”์†Œ๋ฅผ ํ•ด๋‹น ์—ด์˜ ์ตœ๋Œ“๊ฐ’์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ).

# ํ’€์ด
arr = np.array([[1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12],
                [13, 14, 15, 16]])

col_max = np.max(arr, axis=0)  # [13, 14, 15, 16]
normalized = arr / col_max

์š”์•ฝ

๊ธฐ๋Šฅ ํ•จ์ˆ˜/๋ฉ”์„œ๋“œ
๋ฐฐ์—ด ์ƒ์„ฑ np.array(), np.zeros(), np.ones(), np.arange(), np.linspace()
๋ฐฐ์—ด ์†์„ฑ shape, dtype, ndim, size
์ธ๋ฑ์‹ฑ arr[i], arr[i, j], arr[condition], arr[indices]
ํ˜•ํƒœ ๋ณ€ํ™˜ reshape(), flatten(), ravel(), T
์—ฐ์‚ฐ +, -, *, /, np.sum(), np.mean(), np.std()
๊ฒฐํ•ฉ/๋ถ„ํ•  np.vstack(), np.hstack(), np.split()
to navigate between lessons