목차
목차ReferencePractice실습 코드Scalars, Vectors, MatricesTensors (N-dimensional array)Definining Numpy arrays상수로 채우기난수로 채우기arangeIndexing & Slicing
Reference
Programming for AI (AI504) at KAIST GSAI
Practice 1 : Numpy
Practice
Practice는 Jupiter notebook을 이용하여, Google Colab에서 진행됩니다.
공개되어 있는 실습 코드 내
.ipynb
파일들을 Colab에서 열어서 사용하시면 됩니다.제 글의 코드 중 일부는, 여러 가지 방법을 테스트하는 과정에서 원본 코드와 다르게 변형되었습니다.
실습 코드
numpy library를 import합니다.
import numpy as np
아래는 뒤에서 유용하게 사용할 함수들입니다.
def print_obj(obj, name): print("%s:\n%s\n" % (name, obj)) def check_each(a, b): return (a == b).astype('bool') def check_mean(a, b): return np.mean(a == b).astype('bool')
Scalars, Vectors, Matrices
Numpy의 array를 선언합니다. 여러 가지 차원으로 만들 수 있습니다.
Scalar 값이 1. 과 같이 표시된 것은, float type임을 나타냅니다.
a = np.array(1.) b = np.array([1., 2., 3.]) c = np.array([[1., 2., 3.], [4., 5., 6.]])
print_obj(a, "a") print_obj(b, "b") print_obj(c, "c")
출력 결과
a:
1.0
b:
[1. 2. 3.]
c:
[[1. 2. 3.]
[4. 5. 6.]]
ndim
은 Numpy array의 차원을 나타내는 값입니다. scalar 값은 0차원입니다.print_obj(a.ndim, "a.ndim") print_obj(b.ndim, "b.ndim") print_obj(c.ndim, "c.ndim")
출력 결과
a.ndim:
0
b.ndim:
1
c.ndim:
2
shape
는 Numpy array의 각 차원별 길이라고 생각할 수 있습니다. 예를 들어 길이 3의 1차원 배열이 2개 들어있는 c는 (2, 3)입니다.Shape가 헷갈릴 때를 대비하여 제가 찾은 방법은, 가장 바깥쪽부터 Tree를 순회하듯이 안으로 들어가며 child의 개수를 센다고 생각하는 것입니다.
c = [[1., 2., 3.], [4., 5., 6.]] 을 생각해보면, 가장 바깥에서 보았을 때 2개의 child(1차원 배열)를 가집니다. 각 child(1차원 배열)는 3개의 child(scalar)를 가집니다. 순서대로 써 주면 (2, 3)입니다.
print_obj(a.shape, "a.shape") print_obj(b.shape, "b.shape") print_obj(c.shape, "c.shape")
출력 결과
a.shape:
()
b.shape:
(3,)
c.shape:
(2, 3)
Tensors (N-dimensional array)
더 높은 차원에서도 같은 기능을 사용할 수 있습니다.
d = np.array([[[1., 2., 3.], [4., 5., 6.]], [[7., 8., 9.], [10., 11., 12.]]]) e = np.array([[[[1., 2., 3.], [1., 2., 3.]], [[4., 5., 6.], [4., 5., 6.]]], [[[7., 8., 9.], [7., 8., 9.]], [[10., 11., 12.], [10., 11., 12.]]]])
print_obj(d, "d") print_obj(d.ndim, "d.ndim") print_obj(d.shape, "d.shape") print_obj(e, "e") print_obj(e.ndim, "e.ndim") print_obj(e.shape, "e.shape")
출력 결과
d:
[[[ 1. 2. 3.]
[ 4. 5. 6.]]
[[ 7. 8. 9.]
[10. 11. 12.]]]
d.ndim:
3
d.shape:
(2, 2, 3)
e:
[[[[ 1. 2. 3.]
[ 1. 2. 3.]]
[[ 4. 5. 6.]
[ 4. 5. 6.]]]
[[[ 7. 8. 9.]
[ 7. 8. 9.]]
[[10. 11. 12.]
[10. 11. 12.]]]]
e.ndim:
4
e.shape:
(2, 2, 2, 3)
# Quiz: What is the shape of [[[1], [2], [3]], [[4], [5], [6]]]?
코드
example = np.array([[[1], [2], [3]], [[4], [5], [6]]]) print(example.shape)
출력 결과
example = np.array([[[1], [2], [3]], [[4], [5], [6]]])
print(example.shape)
Definining Numpy arrays
원하는 값이 들어 있는 Numpy array를 선언하는 방법들입니다.
상수로 채우기
numpy.ones()
: 1. 으로 채워진 array를 원하는 shape에 맞게 만듭니다.- 공식 문서에 나타난 함수 형태는
numpy.ones(
shape
,
dtype=None
,
order='C'
,
*
,
device=None
,
like=None
)
입니다.
a = np.ones(10) print(a) a = np.ones((2, 5)) print(a)
출력 결과
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
numpy.zeros()
: 0. 으로 채워진 array를 원하는 shape에 맞게 만듭니다.- 공식 문서에 나타난 함수 형태는
numpy.zeros(
shape
,
dtype=float
,
order='C'
,
*
,
like=None
)
입니다.
a = np.zeros((2, 5)) a
출력 결과
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
numpy.full()
: 원하는 값으로 채워진 array를 원하는 shape에 맞게 만듭니다.- 공식 문서에 나타난 함수 형태는
numpy.full(
shape
,
fill_value
,
dtype=None
,
order='C'
,
*
,
device=None
,
like=None
)
입니다.
a = np.full((2,5), 5) a
출력 결과
array([[5, 5, 5, 5, 5],
[5, 5, 5, 5, 5]])
난수로 채우기
numpy.random.random()
: [0.0, 1.0) 범위의 랜덤 값을 원하는 shape에 맞게 채운 array를 만듭니다.- 공식 문서에 나타난 함수 형태는
random.random(
size=None
)
입니다. numpy.random.random_sample()
의 alias입니다. 이 함수의 공식 문서를 따라가 보면, 균일 분포(Uniform distribution)를 따르는 것을 확인할 수 있습니다. 를 따르는 난수를 만들고 싶다면,(b - a) * random_sample() + a
와 같이 사용하면 됩니다.
a = np.random.random((2, 3, 4)) a
출력 결과 (random 값)
array([[[0.24357383, 0.34716465, 0.14068691, 0.05884086],
[0.3063829 , 0.11157136, 0.38942725, 0.72143984],
[0.28681114, 0.56505687, 0.5016722 , 0.44774679]],
[[0.44229731, 0.85518321, 0.21396388, 0.91448339],
[0.21117673, 0.3398618 , 0.79922104, 0.62609722],
[0.86361199, 0.16361286, 0.92321251, 0.91571351]]])
numpy.random.normal()
: 정규분포(Normal distribution)를 따르는 난수를 원하는 shape에 맞게 채운 array를 만듭니다.- 공식 문서에 나타난 함수 형태는
random.normal(
loc=0.0
,
scale=1.0
,
size=None
)
입니다. loc은 평균(Mean), scale은 표준편차(Standard deviation)에 해당하는 값입니다.
a = np.random.normal(0, 10, (2, 3, 4)) a
출력 결과 (random 값)
array([[[-30.09166202, 15.35941141, -6.52358696, 21.21958735],
[ -6.71765646, -7.10020775, -6.01215388, 9.61856523],
[ 9.95170664, 4.79350909, 6.13716296, -0.50547168]],
[[ 1.12400471, -15.01510694, -20.61491567, 4.60278202],
[ 2.94193321, 3.61323383, 6.09604655, -15.6912707 ],
[-14.6617754 , -12.05169949, -5.27005904, 11.72837321]]])
arange
Python의 range 객체와 유사한 개념입니다. 0, 1, 2, … 가 순서대로 채워진 array를 만듭니다.
a = np.arange(10) a
출력 결과
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
astype()
으로 type을 지정할 수 있습니다. a = np.arange(10).astype(float) a
출력 결과
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
reshape()
는 Numpy array의 모양을 바꿔 줍니다.a = np.arange(10).reshape((5,2)) a
출력 결과
array([[0, 1],
[2, 3],
[4, 5],
[6, 7],
[8, 9]])
# Quiz: Create a 4-by-3-by-2 tensor filled with 0.0 to 23.0
코드
example2 = np.arange(24).astype(float).reshape((4, 3, 2)) example2
출력 결과
array([[[ 0., 1.],
[ 2., 3.],
[ 4., 5.]],
[[ 6., 7.],
[ 8., 9.],
[10., 11.]],
[[12., 13.],
[14., 15.],
[16., 17.]],
[[18., 19.],
[20., 21.],
[22., 23.]]])
Indexing & Slicing
Python에서 기본으로 제공하는 Indexing과 Slicing을 그대로 사용할 수 있습니다. Python 문법과 일치하기에, 출력 결과는 생략합니다.
# Indexing and slicing a vector a = np.arange(10) print_obj(a, "a") print_obj(a[0], "a[0]") print_obj(a[1], "a[1]") print_obj(a[-1], "a[-1]") print_obj(a[-3], "a[-3]") print_obj(a[0:10], "a[0:10]") print_obj(a[0:], "a[0:]") print_obj(a[:10], "a[:10]") print_obj(a[:], "a[:]") print_obj(a[7:], "a[7:]") print_obj(a[:5], "a[:5]") print_obj(a[2:5], "a[2:5]") # Quiz: What is a[-4:]? # Quiz: What is a[:-8]? print_obj(a[0:10:2], "a[0:10:2]") print_obj(a[0:10:3], "a[0:10:3]") print_obj(a[2:6:3], "a[2:6:3]") print_obj(a[::-1], "a[::-1]") print_obj(a[8:5:-1], "a[8:5:-1]") print_obj(a[8:5], "a[8:5]") # Quiz: Create [9, 6, 3] using a. print_obj(a[:2:-3], "a[:2:-3]")
# Indexing a matrix a = np.arange(9).reshape((3,3)) print_obj(a, "a") print_obj(a[0][0], "a[0][0]") print_obj(a[0,0], "a[0,0]") print_obj(a[1,1], "a[1,1]") print_obj(a[1,0], "a[1:0]") # Quiz: How to access the last row? print_obj(a[2], "a[2]") print_obj(a[-1], "a[-1]") # Quiz: How to access the second column? print_obj(a[:,1], "a[:,1]") # Quiz: How to create [8, 5] using a? print_obj(a[:0:-1, 2], "a[:0:-1, 2]")
# Indexing and slicing a 3D tensor a = np.arange(4*3*2).reshape((4, 3, 2)) print_obj(a, "a") print_obj(a[2, 1, 0], "a[2, 1, 0]") # Quiz: What would be a[0]? print_obj(a[0], "a[0]") # Quiz: What would be a[0, 1]? print_obj(a[0,1], "a[0,1]") # Quiz: Create [[0, 2, 4], [6, 8, 10]] print_obj(a[:2, :, 0], "a[:2, :, 0]")
마찬가지로 (To be written..)