๐Ÿ–ฅ๏ธ[Python] 8. Numpy ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

thisk336ยท2023๋…„ 9์›” 30์ผ
0

Python

๋ชฉ๋ก ๋ณด๊ธฐ
14/17
post-thumbnail

Numpy ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • Numerical computing with Python์˜ ์•ฝ์ž๋กœ ์ˆ˜์น˜์—ฐ์‚ฐ ๋ฐ ๋ฒกํ„ฐ ์—ฐ์‚ฐ์— ์ตœ์ ํ™”๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.
  • 2005๋…„์— ๋งŒ๋“ค์–ด์กŒ์œผ๋ฉฐ, ์˜คํ”ˆ์†Œ์Šค์ด๋‹ค.
  • ์ตœ์ ํ™”๋œ C code๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ์–ด ์ข‹์€ ์„ฑ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • ํŒŒ์ด์ฌ๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ˆ˜์น˜ ์—ฐ์‚ฐ์˜ ์•ˆ์ •์„ฑ์ด ๋ณด์žฅ๋˜์–ด ์žˆ๋‹ค.
  • N์ฐจ์› ์‹ค์ˆ˜๊ฐ’ ์—ฐ์‚ฐ์— ์ตœ์ ํ™”๋˜์–ด ์žˆ๋‹ค.
import numpy as np

arr = np.array([1, 2, 3])
print(np.linalg.norm(arr))

Numpy๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ 

  • ๋ฐ์ดํ„ฐ๋Š” ๋ฒกํ„ฐ๋กœ ํ‘œํ˜„๋˜๋ฉฐ, ๋ฐ์ดํ„ฐ ๋ถ„์„์„ ํ•˜๋ ค๋ฉด ํ•„์ˆ˜์ ์œผ๋กœ ๋ฒกํ„ฐ ์—ฐ์‚ฐ์„ ํ•˜๊ฒŒ ๋œ๋‹ค.
  • ์ˆ˜์น˜ ์—ฐ์‚ฐ์— ์•ˆ์ •์„ฑ์ด ๋ณด์žฅ๋˜์–ด ์žˆ์–ด ๋งŽ์€ ์‹ค์ˆ˜ ์—ฐ์‚ฐ์ด ์š”๊ตฌ๋˜๋Š” ๋จธ์‹ ๋Ÿฌ๋‹์—์„œ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • numpy๋Š” ๋ฒกํ„ฐ ์—ฐ์‚ฐ์„ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์— ์ตœ์ ํ™”๋˜์–ด ์žˆ์–ด ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋†’์€ ์†๋„๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

Numpy array

  • Numpy array๋Š” C์–ธ์–ด์˜ array ๊ตฌ์กฐ์™€ ๋™์ผํ•œ ๊ฐœ๋…์ด๋ฉฐ, ํŒŒ์ด์ฌ ๋ฆฌ์ŠคํŠธ์™€ ๋น„์Šทํ•œ ๊ตฌ์กฐ์ง€๋งŒ ์„ธ๋ถ€์ ์ธ ํŠน์ง•์ด ๋‹ค๋ฅด๋‹ค.
  1. <๋ฆฌ์ŠคํŠธ์™€ ๊ณตํ†ต์ >
  • indexing์œผ๋กœ ์›์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ƒ์„ฑ ํ›„ assignment operator๋ฅผ ์ด์šฉํ•˜์—ฌ ์›์†Œ์˜ update๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
  1. <๋ฆฌ์ŠคํŠธ์™€ ์ฐจ์ด์ >
  • ์„ ์–ธํ•œ ์ดํ›„์— ํฌ๊ธฐ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋ชจ๋“  ์›์†Œ์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด ๋™์ผํ•ด์•ผ ํ•œ๋‹ค.

Numpy Array ์ƒ์„ฑ

# ํŒŒ์ด์ฌ ๋ฆฌ์ŠคํŠธ ์„ ์–ธ
data = [1, 2, 3, 4, 5]

# ํŒŒ์ด์ฌ 2์ฐจ์› ๋ฆฌ์ŠคํŠธ(ํ–‰๋ ฌ) ์„ ์–ธ
data2 = [[1, 2], [3, 4]]

# ํŒŒ์ด์ฌ list๋ฅผ numpy array๋กœ ๋ณ€ํ™˜
arr = np.array(data)
# arr = np.array([1, 2, 3, 4, 5]) ๊ฐ™์€ ๋ฐฐ์—ด

# 2์ฐจ์› ๋ฆฌ์ŠคํŠธ๋ฅผ np.array๋กœ ๋งŒ๋“ฆ
arr2 = np.array(data2)

์—ฐ์†๋œ ์ˆซ์ž๋ฅผ Numpy Array๋กœ ํ‘œํ˜„ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

# 0๋ถ€ํ„ฐ 9๊นŒ์ง€ ์ˆซ์ž๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ array (๊ฐ™์€ ๊ฒฐ๊ณผ)
np.array(list(range(10)))
np.arange(10)

# 10๋ถ€ํ„ฐ 99๊นŒ์ง€ ์ˆซ์ž๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ array (๊ฐ™์€ ๊ฒฐ๊ณผ)
np.array(list(range(10, 100)))
np.arange(10, 100)

Numpy Array์˜ ํฌ๊ธฐ๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด shape ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

arr.shape # (5, ) != (5, 1)
arr2.shape # (2, 2)

Reshaping array

# 3 x 3 ํ–‰๋ ฌ ์ƒ์„ฑ
x = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])

# ์ด์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ณ ์ž ํ•œ๋‹ค๋ฉด reshape ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
np.arange(1, 10).reshape(3, 3) # (9, ) -> (3, 3)

# row vector๋ฅผ column vector๋กœ
np.arange(6).reshape(6, 1)

# ํŽผ์น˜๊ธฐ
x.reshape(-1, )

๋ฐฐ์—ด ํ•ฉ์น˜๊ธฐ

arr1 = np.array([[1, 2, 3]])
arr2 = np.array([[4, 5, 6]])
# arr1 + arr2 = ?
# L = [1, 2, 3]
# L2 = [4, 5, 6]
# L + L2
# arr1์™€ arr2๋ฅผ ํ•ฉ์นจ
np.concatenate([arr1, arr2], axis=0)

๊ฐ€๋กœ ๋˜๋Š” ์„ธ๋กœ๋ฅผ ์ง€์ •ํ•ด์„œ ํ•ฉ์น˜๊ณ  ์‹ถ์œผ๋ฉด vstack, hstack ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

# stacking vertically
np.vstack([arr1, arr2])

# stacking horizontally
np.hstack([arr1, arr2])

Numpy ์—ฐ์‚ฐ = vector ์—ฐ์‚ฐ

# v1 = (1, 2, 3), v2 = (4, 5, 6) ๋ฒกํ„ฐ 2๊ฐœ ์ƒ์„ฑ
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])

# ๋ฆฌ์ŠคํŠธ๋กœ ๋”ํ•˜๊ธฐ ์—ฐ์‚ฐ
L = [1, 2, 3]
L2 = [4, 5, 6]
L + L2

#  vector addition
v1 + v2

#  vector subtraction
v1 - v2

# (not vector operation) elementwise multiplication
v1 * v2

# (not vector operation) elementwise division
v1 / v2

# dot product
v1 @ v2 # 1x4 + 2x5 + 3x6

Broadcast, Universal Function

  • Broadcast๋ž€ ์„œ๋กœ ํฌ๊ธฐ๊ฐ€ ๋‹ค๋ฅธ numpy array๋ฅผ ์—ฐ์‚ฐํ•  ๋•Œ, ์ž๋™์œผ๋กœ ์—ฐ์‚ฐ์„ ์ „ํŒŒ(broadcast)ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ. ํ–‰๋ ฌ๊ณฑ ์—ฐ์‚ฐ์„ ํ•  ๋•Œ ํŽธ๋ฆฌํ•˜๋‹ค.
arr1 = np.array([1, 2, 3])

arr2 = np.array([[-1, -1, -1],
                 [1, 1, 1]])
arr2.shape

# 2๊ฐœ์˜ array๋ฅผ ํ•ฉ ์—ฐ์‚ฐ
arr1 + arr2

out : array([[0, 1, 2], [2, 3, 4]])

# 2๊ฐœ์˜ array๋ฅผ ๊ณฑ ์—ฐ์‚ฐ
arr1 * arr2

out : array([[-1, -2, -3], [1, 2, 3]])

  • Universal Function์ด๋ž€ broadcast ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•ด์„œ, numpy array์˜ ๋ชจ๋“  ์›์†Œ์— ๋™์ผํ•œ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ์ ์šฉํ•œ ๊ฒƒ๊ณผ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋‚ด๋Š” ๊ธฐ๋Šฅ.
# ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ํ‘œํ˜„ํ•œ ์ฝ”๋“œ
arr1.shape[0]

f = lambda x : 1/x

arr1 = np.array([1., 2., 3.])

for i in range(arr1.shape[0]):
  arr1[i] = f(arr1[i])
print(arr1)

# Universal Function์„ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ
arr1 = np.array([1., 2., 3.])
print(1 / arr1) # universal func

Indexing

  • numpy array์˜ indexing์€ python list์˜ indexing๊ณผ ๊ฐ™๋‹ค.
arr1 = np.arange(10)

# ์ฒซ๋ฒˆ์งธ ์›์†Œ
arr1[0]

# ๋งˆ์ง€๋ง‰ ์›์†Œ
arr1[-1]

# ์•ž์—์„œ๋ถ€ํ„ฐ ์›์†Œ 3๊ฐœ slicing
arr1[:3]

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

# arr2์˜ 2th row, 3th column ์›์†Œ = 7
arr2[1][2]
arr2[1, 2]

# arr2์˜ ์„ธ๋ฒˆ์งธ column [3, 7, 11]
arr2[0, 2]
arr2[1, 2]
arr2[2, 2]
arr2[:, 2]

# arr2์˜ ๋‘๋ฒˆ์งธ row
arr2[0:2, 0:2] # arr2[1]

Numpy์˜ ํ•จ์ˆ˜

# random sampling
mat1 = np.random.randn(5, 3)
mat1

# ์ ˆ๋Œ€๊ฐ’ ์”Œ์šฐ๊ธฐ
np.abs(mat1)

# ์ œ๊ณฑํ•˜๊ธฐ
np.square(mat1)

# ์ œ๊ณฑ๊ทผ ๊ตฌํ•˜๊ธฐ
np.sqrt(mat1)
  • ๋˜ํ•œ Numpy์—์„œ๋Š” ์„ ํ˜•๋Œ€์ˆ˜๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
# linear algebra functions
vec = np.array([1, 2, 2])
mat = np.array([[1, 2],
               [3, 4]])

# ํ–‰๋ ฌ์‹
np.linalg.det(mat)

# ์—ญํ–‰๋ ฌ
np.linalg.inv(mat)

# 1norm
np.linalg.norm(vec)

# ๊ณ ์œ ๊ฐ’, ๊ณ ์œ ๋ฒกํ„ฐ
np.linalg.eig(mat)

# ์„ ํ˜•์—ฐ๋ฆฝ๋ฐฉ์ •์‹์˜ ํ•ด
a = np.array([10, 15])
np.linalg.solve(mat,a)

Aggregation functions

mat2 = np.random.rand(3, 2)
mat2

# Summation
np.sum(mat2)
np.sum(mat2, axis=0) # row ๋ฐฉํ–ฅ ํ•ฉ๊ณ„
np.sum(mat2, axis=1) # column ๋ฐฉํ–ฅ ํ•ฉ๊ณ„

# mean
np.mean(mat2)
np.mean(mat2, axis=0) # row ๋ฐฉํ–ฅ ํ‰๊ท 
np.mean(mat2, axis=1) # column ๋ฐฉํ–ฅ ํ‰๊ท 

# std
np.std(mat2)

# min, max
np.min(mat2, axis=0) # ๊ฐ row์— ๋Œ€ํ•œ ์ตœ์†Œ๊ฐ’
np.max(mat2, axis=1) # ๊ฐ column์— ๋Œ€ํ•œ ์ตœ๋Œ€๊ฐ’

# ์ตœ์†Œ๊ฐ’์ด ์žˆ๋Š” Index
np.argmin(mat2, axis=0)

# ์ตœ๋Œ€๊ฐ’์ด ์žˆ๋Š” Index
np.argmax(mat2, axis=1)

# ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ
np.sort(mat2, axis=0)

# ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ
#np.sort(mat2, axis=0)[::-1]

# index๋ฅผ ์ •๋ ฌ
np.argsort(mat2, axis=0)

0๊ฐœ์˜ ๋Œ“๊ธ€