넘파이는 무려 C언어로 구현된 파이썬 라이브러리로써, 고성능의 수치계산을 위해 제작되었습니다.
그리고 아마 추후 적을(?) Pandas와 matplotlib 라이브러리와도 연관이 있다고 합니다.
이 글에서는 기본 함수들을 알아보도록 하겠습니다.
import numpy as np
import, 예전에 썼던 글에서도 sys 라이브러리를 불러올 때에도 사용했던 것입니다.
이번에는 numpy를 불러오고, 그것을 np라고 짧게 명시하겠습니다.
(그냥 import numpy만 써도 가능합니다. 하지만 코드 작성의 편의를 위해 많은 분들이 np를 사용하고 있습니다.)
array, shape, ndim
array1 = np.array([1, 2, 3])
print(array1)
print("array1 type: ", type(array1))
print("array1 shape: ", array1.shape)
print("array1 : {}차원".format(array1.ndim))
'''
[1 2 3]
array1 type: <class 'numpy.ndarray'>
array1 shape: (3,)
array1 : 1차원
'''
넘파이를 이용해 배열을 만들어 보았습니다.
이렇게 넘파이로 만든 배열의 타입은 <class 'numpy.ndarray'>, 크기는 3, 차원은 1인 것을 확인할 수 있습니다.
array2 = np.array([[1, 2, 3], [2, 3, 4]])
print("array2 type: ", type(array2))
print("array2 shape: ", array2.shape)
print("array2: {}차원".format(array2.ndim))
'''
array2 type: <class 'numpy.ndarray'>
array2 shape: (2, 3)
array2: 2차원
'''
2차원 배열에도 동일하게 적용됩니다. shape와 ndim의 값만 달라진 것을 확인할 수 있습니다.
array3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(array3d)
print(array3d.tolist())
print("array3d type: ", type(array3d))
print("array3d shape: ", array3d.shape)
print("array3d: {}차원".format(array3d.ndim))
'''
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
array3d type: <class 'numpy.ndarray'>
array3d shape: (2, 2, 2)
array3d: 3차원
'''
3차원 배열에서도 깔끔하게 출력되는 것을 확인할 수 있습니다.
dtype
list1 = [1, 2, 3]
array1 = np.array(list1)
print(array1, array1.dtype)
'''
[1 2 3] int64
'''
dtype은 배열의 타입을 확인하는 함수입니다.
정수형 자료들만 배열에 있기 때문에 int64가 출력됩니다.
list2 = [1, 2, 3.0]
array2 = np.array(list2)
print(type(array2))
print(array2, array2.dtype)
'''
<class 'numpy.ndarray'>
[1. 2. 3.] float64
'''
위 배열에는 3.0 이라는 소수가 들어가 있어서 float64라는 결과가 나오게 됩니다.
그럼, 저 자료형은 어떻게 바꾸는 걸까요?
astype
array_float1 = np.array([1.1, 2.1, 3.1])
array_int1 = array_float1.astype("int64")
print(array_int1, array_int1.dtype)
'''
[1 2 3] int64
'''
바로 astype 함수를 통해 배열의 자료형을 변경할 수 있습니다.
배열의 값들이 모두 소수인데, int64로 바꾸는 순간 정수형으로 변했기 때문에 소숫점이 날아가고 1 2 3만이 출력됩니다.
sum, axis
array3 = np.array([[1, 2, 3],
[2, 3, 4]])
print(array3.sum())
print(array3.sum(axis = 0))
print(array3.sum(axis = 1))
'''
15
[3 5 7]
[6 9]
'''
sum 함수와 axis입니다.
말 그대로 sum은 배열 내 모든 값들을 더하는 함수입니다. 하지만 여기서 axis는 생소할 수 있는데요,
0을 참조하면 각각 배열의 가로를, 1이면 각각 배열의 세로로 더한 값이 출력됩니다.
선형대수(Linear Algebra)의 데이터 유형 중 스칼라(x ∈ R), 벡터 등과 연관되어 있다는데 여기서는 자세히 다루지는 않겠습니다..
arange
arange_array = np.arange(10)
print(arange_array)
print(arange_array.shape, arange_array.dtype)
'''
[0 1 2 3 4 5 6 7 8 9]
(10,) int64
'''
배열을 생성하는 함수입니다.
0부터 시작하기 때문에 10을 쓰면 0부터 9까지가 배열에 채워집니다.
zeros
zeros_array = np.zeros((2, 2))
print(zeros_array)
print(zeros_array.shape, zeros_array.dtype)
'''
[[0. 0.]
[0. 0.]]
(2, 2) float64
'''
배열 내 값들을 모두 0으로 바꿔버리는 함수입니다. 배열의 크기는 변하지 않습니다.
여기서, 값을 따로 주지 않으면 항상 64가 출력되는데 그 이유는 64가 기본값이기 때문입니다.
ones
ones_array = np.ones((2, 2))
print(ones_array)
print(ones_array.shape, ones_array.dtype)
'''
[[1. 1.]
[1. 1.]]
(2, 2) float64
'''
zeros와 반대로 모든 것을 1로 바꿔버립니다. 역시 배열 크기에는 영향을 주지 않습니다.
reshape
import numpy as np
array1 = np.arange(10)
print("array1: \n", array1)
reshape_array1 = array1.reshape(2, 5)
print("reshape_array1: \n", reshape_array1)
reshape_array11 = array1.reshape(5, 2)
print("reshape_array11: \n", reshape_array11)
'''
array1:
[0 1 2 3 4 5 6 7 8 9]
reshape_array1:
[[0 1 2 3 4]
[5 6 7 8 9]]
reshape_array11:
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
'''
말 그대로 배열의 생김새를 바꿔주는 함수입니다.
처음에 arange로 0 1 2 3 4 5 6 7 8 9가 들어있는 배열을 생성했는데 reshape(2, 5)를 하자 세로 2칸, 가로 5칸이 되는 모습을 볼 수 있습니다.
반대로 5, 2를 입력하면 세로 5칸, 가로 2칸이 됩니다.
indexing
indexing_array1 = np.arange(1, 10)
print("indexing_array1: ", indexing_array1)
value = indexing_array1[2]
print("value: ", value)
print("맨 뒤의 값: ", indexing_array1[-1], "\n맨 뒤에서 두 번째 값: ", indexing_array1[-2])
'''
indexing_array1: [1 2 3 4 5 6 7 8 9]
value: 3
맨 뒤의 값: 9
맨 뒤에서 두 번째 값: 8
'''
C언어의 인덱스처럼 파이썬 넘파이에서도 배열 인덱스를 사용할 수 있습니다.
sclicing
slicing_array1 = np.arange(1, 10)
slicing_array2 = slicing_array1[2:7]
print(slicing_array1, slicing_array2, type(slicing_array1), sep = "\n")
'''
[1 2 3 4 5 6 7 8 9]
[3 4 5 6 7]
<class 'numpy.ndarray'>
'''
대괄호 안에 저런 형식으로 넣게 될 경우 3번째 값부터 7번째 값까지 불러오게 됩니다.
fancy
fancy_array = np.arange(1, 10)
print(fancy_array)
print(fancy_array[[1, 4, 6]])
'''
[1 2 3 4 5 6 7 8 9]
[2 5 7]
'''
왜 이름이 fancy인지 모르겠는 함수입니다.
이 함수는 그 위치에 있는 값들만 불러옵니다.
boolean
import numpy as np
boolean_array1 = np.arange(1, 10)
boolean_array2 = boolean_array1[boolean_array1 > 4]
print("boolean_array1에서 4보다 큰 결과 값: ", boolean_array2)
'''
boolean_array1에서 4보다 큰 결과 값: [5 6 7 8 9]
'''
어떤 특정 배열 값에서 조건보다 큰 값들을 반환하는 함수입니다.
sort
import numpy as np
not_sort_array = np.array([5, 7, 9, 4, 6])
print("본래 행렬: ", not_sort_array)
np_sort_array = np.sort(not_sort_array)
print("nd.sort() 정렬한 후 반환된 행렬: ", np_sort_array)
print("nd.sort() 정렬한 후 원본 행렬: ", not_sort_array)
ndarray_sort_array = not_sort_array.sort()
not_sort_array.sort()
print("nd.sort() 정렬한 후 반환된 행렬: ", ndarray_sort_array)
print("nd.sort() 정렬한 후 원본 행렬: ", not_sort_array)
'''
본래 행렬: [5 7 9 4 6]
nd.sort() 정렬한 후 반환된 행렬: [4 5 6 7 9]
nd.sort() 정렬한 후 원본 행렬: [5 7 9 4 6]
nd.sort() 정렬한 후 반환된 행렬: None
nd.sort() 정렬한 후 원본 행렬: [4 5 6 7 9]
'''
배열의 값들을 정렬해주는 함수입니다.
정렬을 정렬(?)하려 할 경우 None을 반환합니다.
argsort
argsort_array = np.array([5, 7, 9, 4, 6])
print(np.sort(argsort_array))
sort_index = np.argsort(argsort_array)
print(type(sort_index))
print("행렬을 정렬했을 때 원본 행렬의 인덱스: ", sort_index)
'''
[4 5 6 7 9]
<class 'numpy.ndarray'>
행렬을 정렬했을 때 원본 행렬의 인덱스: [3 0 4 1 2]
'''
배열을 정렬했을 때, 그 값들의 인덱스를 출력하는 함수입니다.
5 7 9 4 6을 정렬하면 4가 가장 첫번째로 오는데, 4의 인덱스는 3이니까 3, 5의 인덱스는 0이니까 0... 이런 식으로 출력되게 됩니다.
dot
dot1 = np.array([[1, 2, 3],
[4, 5, 6]])
dot2 = np.array([[7, 8],
[9, 10],
[11, 12]])
doted = np.dot(dot1, dot2)
print("행렬 내적 결과: \n", doted)
'''
행렬 내적 결과:
[[ 58 64]
[139 154]]
'''
해당 함수를 들어가기 전, 잠깐 '행렬'이라는 것을 알아가야 할 필요가 있습니다.
행렬은 선형대수학에서 쓰이는 개념으로, 1개 이상의 수나 식을 직사각형의 배열로 나열한 것을 말합니다.
dot 함수는 행렬곱을 해주는 함수입니다.
행렬곱은 이렇게 정의할 수 있습니다.
이해하기 쉽게 하기 위하여 위에서 쓴 dot1 배열을 행렬곱 해보겠습니다.
[1, 2, 3] [4, 5, 6]. 이것을 행렬곱 하면 (1 × 4) + (2 × 5) + (3 × 6) = 32 라는 결과가 나오게 됩니다.
dot1과 dot2를 행렬곱 하면 첫번째 값은 (1 × 7) + (2 × 9) + (3 × 11) = 58,
(1 × 8) + (2 × 10) + (3 × 12) = 64,
(4 × 7) + (5 × 9) + (6 × 11) = 139,
맨 마지막 값은 (4 × 8) + (5 × 10) + (6 × 12) = 154가 나오게 됩니다.
transpose
transpose_array = np.array([[1, 2, 3],
[4, 5, 6]])
transpose = np.transpose(transpose_array)
print("transpose_array의 전치 행렬: ", transpose)
'''
transpose_array의 전치 행렬: [[1 4]
[2 5]
[3 6]]
'''
trans + pose = 배열의 자세를 바꿔준다고 생각하면 쉽습니다.
'🖥️ 프로그래밍' 카테고리의 다른 글
행렬, 테이블을 넘어 그래프로 - Matplotlib (0) | 2022.05.29 |
---|---|
데이터 조작과 분석 + 테이블까지, pandas (0) | 2022.05.23 |
코드 분석 - 포인터와 배열 (0) | 2022.04.17 |
보다 더 많은 양의 데이터를 편하게! - 배열과 문자열 (0) | 2022.04.12 |
C언어의 첫번째 고비 - 반복문 (for) (0) | 2022.04.04 |