일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- subplot
- Numpy
- 가능도
- unstack
- dtype
- boolean & fancy index
- BOXPLOT
- Python 특징
- 표집분포
- VSCode
- type hints
- Comparisons
- ndarray
- 최대가능도 추정법
- Array operations
- Numpy data I/O
- Operation function
- Python 유래
- scatter
- linalg
- 카테고리분포 MLE
- 부스트캠프 AI테크
- seaborn
- Python
- groupby
- pivot table
- namedtuple
- python 문법
- 정규분포 MLE
- 딥러닝
- Today
- Total
또르르's 개발 Story
[06] Python numpy 본문
Python에서 머신러닝, 딥러닝을 수행하기 위해서 행렬 연산, 매트릭스 연산이 필수적입니다.
numpy는 파이썬의 이학/공학 계산용 패키지를 제공해주며, Matrix와 Vector연산에서 사실상의 표준 라이브러리입니다.
numpy의 특징은 dynamic typing을 사용하지 않기 때문에
- python의 List에 비해 빠르고 메모리도 효율적이고,
- 반복문 없이 데이터 배열에 대한 처리를 지원하며
- 선형대수와 관련된 다양한 기능을 지원
합니다. 이 부분에 대해서는 아래에서 자세하게 설명하겠습니다.
또한, numpy를 사용하기 위해서는 conda에서 numpy를 install 해주어야 합니다.
conda install numpy
numpy를 설치했다면 jupyter notebook이나 pycharm에서 모듈을 import 해줍니다.
일반적으로 numpy는 np라는 alias(별칭)을 사용해서 호출합니다.
import numpy as np
그렇다면 numpy에서 가장 기본인 ndarray에 대해서 정리해보겠습니다.
1️⃣ ndarray
numpy의 array는 아래와 같이 사용합니다.
>>> test_array = np.array([1, 4, 5, 8], float)
>>> print(test_array)
array([1., 4., 5., 8.])
>>> type(test_array[3])
numpy.float64
np.array의 특징은 하나의 데이터 type만 배열에 넣을 수 있다는 것인데 np.array의 두 번째 parameter(float 위치)에 명시해주시면 됩니다.
그래서 아래와 같은 string이나 int형의 데이터 type을 넣더라도 다 float 형식으로 변환됩니다.
>>> test_array = np.array(["1", "4", 5, 8], float)
>>> print(test_array)
array([1., 4., 5., 8.])
✅ 그렇다면 왜 Numpy의 array가 Python의 List보다 효율적일까요?
Numpy array의 생성 방법 때문인데요.
Numpy array는 위에서 말했듯이 dynamic type을 포기했기 때문에 char는 1byte, int는 4byte, string은 8byte와 같이 메모리 간격을 일정하게 만들 수 있습니다. 따라서 array에 직접적으로 값을 저장할 수 있습니다.
하지만 Python List는 dynamic type 때문에 data들은 data의 주소를 가지고 있고, 메모리 어딘가에 저장되어 있는 data값을 다시 한번 참조하게 됩니다. 이렇기 때문에 List는 다양한 data type을 집어넣을 수 있지만, 한 번 더 참조해야 하기 때문에 조금 느리다는 단점이 있습니다.
그래서 Python List를 사용할 때 data값을 비교할 때 메모리 주소가 다르더라도 data값이 같으면 같은 값으로 표시됩니다. List에 저장된 메모리 주소가 같은 data를 가리키기 때문이죠.
a = [1, 2, 3, 4, 5]
b = [5, 4, 3, 2, 1]
>>> a[0] is b[-1] # a[0]과 b[-1]은 index가 다르지만 값 안에 있는 메모리 주소는 같은 메모리(=1)를 가리키기 때문에 같음
True
하지만 np.array는 새로운 메모리를 할당하기 때문에 다른 값이 나오게 됩니다.
a = np.array(a)
b = np.array(b)
>>> a[0] is b[-1]
False
추가적으로 numpy를 사용하면 100,000,000번의 loop가 돌 때, 약 4배 이상의 성능 차이가 난다고 합니다.
속도 차이는
for loop < list comprehension < numpy
순으로 빠르다고 합니다. 그래서 numpy는 대용량 계산에서 많이 사용합니다.
하지만 Concatenate처럼 계산이 아닌, 할당에서는 연산 속도의 이점은 없습니다.
그렇다면 ndarray의 구성요소가 무엇이 있는지 알아보겠습니다.
1) shape : numpy array의 dimension 구성을 반환함
shape은 numpy array의 dimension(차원)이 어떻게 되어있는지 나타냅니다.
그냥 이 행렬이 몇 곱하기 몇 행렬인지를 나타낸다고 생각하시면 됩니다.
a = [[1, 2, 3], [4, 5, 6], [4, 5, 6]]
>>> np.array(a).shape
(3,3)
vector일 경우는 쉼표(,)와 함께 정수 하나가 나옵니다.
>>> test_array = np.array([1, 4, 5, 8], float)
>>> print(test_array.shape)
(4,)
3-tensor(3차원 배열) 일 경우는 tensor의 바깥쪽 배열부터 생각하시면 됩니다.
tensor = [
[[1, 2, 5, 8], [1, 2, 5, 8], [1, 2, 5, 8]],
[[1, 2, 5, 8], [1, 2, 5, 8], [1, 2, 5, 8]],
[[1, 2, 5, 8], [1, 2, 5, 8], [1, 2, 5, 8]],
[[1, 2, 5, 8], [1, 2, 5, 8], [1, 2, 5, 8]],
]
>>> np.array(tensor, int).shape
(4,3,4)
2) dtype : numpy array의 데이터 type을 반환
numpy의 array는 dynamic type이 없기 때문에 type을 지정해주어야 합니다.
dtype은 ndarray의 element가 가지는 data type을 의미하며, 각 element가 차지하는 memory 크기가 결정됩니다.
dtype은 Boolean, integer, float와 같이 기본적인 type에 32, 64와 같이 메모리 크기를 표시해서 사용합니다.
dtype을 float32로 설정했다면 아래 있는 np.array의 크기는 24 bytes입니다.
>>> np.array([[1, 2, 3], [4.5, "5", "6"]], dtype=np.float32).nbytes # 4bytes(32bits) * 6개 = 24bytes
24
dtype을 int8로 설정했다면 아래 있는 np.array의 크기는 6 bytes입니다.
>>> np.array([[1, 2, 3], [4.5, "5", "6"]], dtype=np.int8).nbytes # 1bytes(8bits) * 6개 = 6bytes
6
2️⃣ Handling shape
numpy의 가장 큰 장점은 matrix의 구조를 자유자재로 변경할 수 있는 것입니다.
가장 많이 사용하는 reshape와 flatten에 대해서 정리해보았습니다.
1) reshape : Array의 shape 크기 변경
reshape은 np.array의 shape 형태를 변경합니다.
array의 element의 값이나 개수는 변경되지 않습니다.
>>> test_matrix = [[1, 2, 3, 4], [1, 2, 5, 8]]
>>> np.array(test_matrix).shape
(2, 4)
>>> np.array(test_matrix).reshape(4, 2) # array를 4*2 shape으로 변경
array([[1, 2],
[3, 4],
[1, 2],
[5, 8]])
>>> np.array(test_matrix).reshape(2, 2, 2) # array를 2*2*2 shape으로 변경
array([[[1, 2],
[3, 4]],
[[1, 2],
[5, 8]]])
reshape의 값에 -1을 사용하게 되면 자동으로 값을 계산해서 shape을 구성합니다.
>>> np.array(test_matrix).reshape(2, -1) # -1은 4로 자동 계산해서 들어감
array([[1, 2, 3, 4],
[1, 2, 5, 8]])
2) flatten : 다차원 array를 1차원 array로 변환
flatten은 다차원 array를 1차원으로 변경합니다.
>>> np.array(test_matrix).flatten().shape
(8,)
3️⃣ indexing & slicing
numpy도 list처럼 indexing과 slicing이 가능합니다.
하지만 np.array는 [0,0] 표기법을 제공하면서 훨씬 indexing과 slicing이 편리합니다.
>>> a = np.array([[1, 2, 3], [4.5, 5, 6]], int)
>>> print(a[0,0])
1
>>> print(a[0][0])
1
>>> a[0,0] = 12
>>> print(a)
array([[12, 2, 3],
[ 4, 5, 6]])
slicing은 쉼표(,)를 사용해서 matrix의 부분 집합을 추출할 수 있습니다.
(쉼표를 기준으로 Row, Col을 자르며, Row의 부분과 Col의 부분을 슬라이싱할 수 있습니다.)
a[:2,:] # Row는 0행부터 2행까지, col은 전체
slicing의 3번째 parameter는 step을 나타내며, 이 값을 사용하면 부분 부분의 값 추출이 가능합니다.
✅ numpy의 slicing을 사용하면 indexing을 해서 출력한 것보다 dimension이 하나 더 추가됩니다.
(1 dimension => 2 dimension로 출력, 2 dimension => 3 dimension로 출력)
>>> test_exmaple = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]], int)
>>> test_exmaple[1] # 1 Row의 1열 ~ 2열
array([ 6, 7, 8, 9, 10]) # 1차원 배열
>>> test_exmaple[1:3] # 1 Row ~ 2Row의 전체
array([[ 6, 7, 8, 9, 10]]) # 2차원 배열로 출력
4️⃣ Creation function
1) arange : 범위를 지정해서 ndarray로 반환
arange는 list의 range와 비슷하게 int형태의 범위를 넣으면 그 범위만큼을 array로 만들어주는 명령어입니다.
>>> np.arange(30)
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, 24, 25, 26, 27, 28, 29])
>>> np.arange(0, 10, 0.5) # step지정 가능
array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. , 5.5, 6. ,
6.5, 7. , 7.5, 8. , 8.5, 9. , 9.5])
2) zeros : 0으로 가득 찬 ndarray 생성
zeros는 0으로 초기화한 ndarray입니다.
>>> np.zeros(shape=(10,), dtype=np.int8)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
또는 shape을 지정해서 만들 수 있습니다.
>>> np.zeros((2, 5)) # 2 by 5 - zero matrix 생성
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
3) ones : 1로 가득 찬 ndarray 생성
ones는 1로 초기화한 ndarray입니다.
>>> np.ones(shape=(10,), dtype=np.int8)
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
또는 shape을 지정해서 만들 수 있습니다.
>>> np.ones((2, 5))
array([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
4) empty : 공간만 확보한(메모리 초기화 X) ndarray 생성
empty는 공간만 주어지고 메모리 초기화를 하지 않는 ndarray를 만듭니다.
그래서 이미 사용된 메모리의 값이 들어가 있을 수도 있습니다.
>>> np.empty(shape=(10,), dtype=np.int8)
array([0, 0, -6, 10, 20, -768, 1, 0, 12, 0], dtype=int8)
또는 shape을 지정해서 만들 수 있습니다.
>>> np.empty((10, 5))
array([[3.31183839e-033, 6.98348270e-077, 2.62395837e+179,
1.63649909e-310, 2.34147659e-057],
[1.39804065e-076, 7.57877360e-096, 6.01347002e-154,
7.11517567e-038, 3.24249365e-086],
[1.21089429e-099, 2.42015693e-052, 4.90483617e-062,
1.39804328e-076, 1.14583381e-259],
[4.56335201e-072, 3.11593324e+179, 1.69082216e-310,
1.18295070e-076, 4.08596608e-033],
[8.99060591e-096, 1.39804329e-076, 2.44005307e-154,
3.44353309e-086, 5.20651931e-090],
[1.39736850e-076, 1.39642638e-076, 6.12769454e-062,
1.05162660e-153, 1.39804329e-076],
[5.98149110e-154, 1.74514512e-310, 2.34147661e-057,
1.39804065e-076, 7.57877360e-096],
[4.67296628e-062, 6.98348929e-077, 2.62395837e+179,
6.01334510e-154, 1.48373151e-076],
[7.48418596e-067, 1.39804328e-076, 1.05118731e-153,
8.60961887e-043, 3.24249367e-086],
[1.80286339e-310, 6.01346953e-154, 1.48710114e-076,
8.52243828e-096, 1.39804329e-076]])
5) zeros_like, ones_like, empty_like : 기존 ndarray의 shape 복사
something_like(zeros_like, ones_like, empty_like)는 기존의 shape를 복사해서 사용합니다.
_like앞에 zeros, ones, empty를 붙여주면 됩니다.
>>> np.zeros_like(test_matrix, dtype=np.float32)
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0.]], dtype=float32)
6) identity : 단위행렬(i 행렬) 생성
identity는 단위행렬(대각선이 1인 행렬)을 생성합니다.
>>> np.identity(n=5, dtype=np.int8)
array([[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]], dtype=int8)
7) eye : 단위행렬(i 행렬)에서 1의 시작 위치 변경 가능
eye는 단위행렬에서 1의 시작 위치(k값)를 변경할 수 있습니다.
>>> np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
>>> np.eye(3, 5, k=2)
array([[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
8) diag : 대각 행렬 값 추출
diag는 행렬의 대각 값을 추출합니다.
>>> matrix = np.arange(9).reshape(3, 3)
>>> matrix
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> np.diag(matrix)
array([0, 4, 8])
k를 사용해서 시작 index를 설정할 수 있습니다.
>>> np.diag(matrix, k=1)
array([1,5])
9) random sampling : 데이터 분포에 따른 sampling으로 array 생성
random sampling은 데이터의 분포로 array를 생성하는 방식입니다.
대표적으로 균등 분포와 정규분포가 있습니다.
>>> np.random.uniform(0,1,10).reshape(2,5) # 균등분포
array([[0.81067373, 0.2649121 , 0.06624061, 0.22685301, 0.03607016],
[0.08197913, 0.30253986, 0.86105008, 0.64858921, 0.57669391]])
>>> np.random.normal(0, 1, 10).reshape(2, 5) # 정규분포
array([[-0.14950323, 0.57639207, 1.07549923, 0.69918396, 0.4341872 ],
[ 1.45683959, -0.63192178, 1.75431129, 0.40488555, -1.77115048]])
5️⃣ Operation function
1) sum, mean, std : ndarray의 element들 간의 합, 평균, 표준편차
sum은 array의 합을 구할 수 있습니다.
>>> test_array = np.arange(1, 11)
>>> test_array.sum()
55.0
mean은 array의 평균을 구할 수 있습니다.
>>> test_array.mean()
5.5
std는 array의 표준편차를 구할 수 있습니다.
>>> test_array.std()
2.8722813232690143
sum, mean, std에서는 axis라는 개념을 사용할 수 있는데
axis는 기준이 되는 dimension 축을 선택해 해당 축에 있는 계산 값을 구할 수 있습니다.
(axis 개념이 헷갈리면..
axis = 0일 때 => row이므로 => 해당 값이 관통하면서 4개 통과
axis = 1일 때 => col이므로 => 해당 값이 관통하면서 3개 통과
라고 기억했습니다.)
>>> test_array.sum(axis=1), test_array.sum(axis=0)
(array([10, 26, 42]), array([15, 18, 21, 24]))
3-tensor일 경우에도 axis=0, axis=1, axis=2의 sum을 각각 구할 수 있습니다.
>>> third_order_tensor
array([[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]],
[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]],
[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]]])
>>> third_order_tensor.sum(axis=0)
array([[ 3, 6, 9, 12],
[15, 18, 21, 24],
[27, 30, 33, 36]])
>>> third_order_tensor.sum(axis=1)
array([[15, 18, 21, 24],
[15, 18, 21, 24],
[15, 18, 21, 24]])
>>> third_order_tensor.sum(axis=2)
array([[10, 26, 42],
[10, 26, 42],
[10, 26, 42]])
✅ np.something을 호출하면 다양한 수학 연산자를 확인할 수 있습니다.
2) concatenate : ndarray를 합치는(붙이는) 함수
concatenate는 array를 합치는 함수입니다.
방법은 vstack(vertical), hstack(horizontal), axis 사용이 있습니다.
- vstack
vertical 방향으로 붙일 때 사용합니다.
a = np.array([1, 2, 3])
b = np.array([2, 3, 4])
>>> np.vstack((a, b))
array([[1, 2, 3],
[2, 3, 4]])
- hstack
horizontal 방향으로 붙일 때 사용합니다.
a = np.array([[1], [2], [3]])
b = np.array([[2], [3], [4]])
>>> np.hstack((a, b))
array([[1, 2],
[2, 3],
[3, 4]])
- axis 사용
axis 축을 설정해서 concatenate함수를 사용할 수 있습니다.
a = np.array([[1, 2, 3]])
b = np.array([[2, 3, 4]])
>>> np.concatenate((a, b), axis=0) # vertical 방향으로 붙임
array([[1, 2, 3],
[2, 3, 4]])
a = np.array([[1, 2, 3]])
b = np.array([[2, 3, 4]])
>>> np.concatenate((a, b), axis=1) # horizontal 방향으로 붙임
array([[1, 2, 3, 2, 3, 4]])
a = np.array([[1, 2], [3, 4]])
b = np.array([[5], [6]])
>>> np.concatenate((a, b), axis=1)
array([[1, 2, 5],
[3, 4, 6]])
만약 dimension이 부족해서 concatenate를 하지 못할 때는 np.newaxis를 사용하면 됩니다.
a = np.array([[1, 2], [3, 4]])
b = np.array([5, 6])
b = b[np.newaxis, :] # dimension을 하나 추가함
>>> np.concatenate((a, b.T), axis=1)
array([[1, 2, 5],
[3, 4, 6]])
b가 어떻게 바뀌었는지 모르는 분들을 위해(저도 몰랐음) 다시 한번 쓰면 아래와 같이 됩니다.
>>> b = np.array([5, 6])
>>> print(b)
[5 6]
>>> b = b[np.newaxis, :]
>>> print(b)
[[5 6]]
>>> print(b.T)
[[5]
[6]]
6️⃣ Array operations
1) Operations b/t arrays : array 간의 기본적인 사칙연산(+,-,*)을 지원
>>> test_a = np.array([[1, 2, 3], [4, 5, 6]], float)
>>> test_a + test_a # Matrix + Matrix 연산
array([[ 2., 4., 6.],
[ 8., 10., 12.]])
>>> test_a - test_a # Matrix - Matrix 연산
array([[0., 0., 0.],
[0., 0., 0.]])
>>> test_a * test_a # Matrix내 element들 간 같은 위치에 있는 값들끼리 연산(Element-wise operations)
array([[ 1., 4., 9.],
[16., 25., 36.]])
2) Element-wise operations : array 간의 shape이 같을 때 일어나는 연산
Element-wise operations는 array간의 shape이 같을 때 같은 index끼리 연산을 하는 형태입니다.
특히 이 연산은 곱셈(*) 일 때 주의해야 합니다.
행렬의 곱셈은 대부분 Dot product로 알고 있는데 Python에서 shape이 같을 때 이 연산을 사용해버리면 index가 같은 값끼리만 곱셈을 하게 됩니다.
>>> test_a * test_a # Matrix내 element들 간 같은 위치에 있는 값들끼리 연산(Element-wise operations)
array([[ 1., 4., 9.],
[16., 25., 36.]])
3) Dot product : 행렬의 곱하기 연산
>>> test_a.dot(test_b)
array([[ 58, 64],
[139, 154]])
4) transpose : 전치 행렬
>>> test_a.transpose()
array([[1, 4],
[2, 5],
[3, 6]])
>>> test_a.T
array([[1, 4],
[2, 5],
[3, 6]])
5) broadcasting : shape이 다른 배열 간 연산을 지원하는 기능
broadcasting은 shape이 다른 배열 간에 연산을 할 때 사용합니다.
Matrix와 Scalar 계산, Scalar와 Vector 계산, Vector와 Matrix 계산할 때 boradcasting 방법으로 계산됩니다.
broadcasting 방식은 element가 적은 배열의 값을 복제해 shape 크기를 똑같이 맞춘 다음 Element-wise operations 연산을 수행합니다.
- Matrix와 Scalar Broadcasting
아래는 Matrix와 Scalar를 계산할 때 Scalar의 값이 Matrix의 양만큼 복제돼 연산되는 것을 알 수 있습니다.
>>> test_matrix = np.array([[1, 2, 3], [4, 5, 6]], float)
>>> scalar = 3
>>> test_matrix + scalar # Matrix - Scalar 덧셈
array([[4., 5., 6.],
[7., 8., 9.]])
>>> test_matrix - scalar # Matrix - Scalar 뺄셈
array([[-2., -1., 0.],
[ 1., 2., 3.]])
>>> test_matrix * 5 # Matrix - Scalar 곱셈
array([[ 5., 10., 15.],
[20., 25., 30.]])
>>> test_matrix / 5 # Matrix - Scalar 나눗셈
array([[0.2, 0.4, 0.6],
[0.8, 1. , 1.2]])
- Matrix와 Vector(Matrix) Broadcasting
Matrix와 Vector(Matrix) 간의 연산에서는 Vector(Matrix)의 element를 복사해서 Matrix의 shape과 똑같이 만듭니다.
그런 후에 연산을 진행합니다.
아래 그림과 같이 Vector(Matrix)를 Matrix의 shape과 똑같이 만든 후 연산합니다.
>>> test_matrix = np.arange(1, 13).reshape(4, 3)
>>> test_vector = np.arange(10, 40, 10)
>>> test_matrix + test_vector
array([11, 22, 33],
[14, 25, 36],
[17, 28, 39],
[20, 31, 42]])
7️⃣ Comparisons
기본적으로 array에서 어떤 값과 비교를 하면 array 형태로 반환됩니다.
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a < 4
array([ True, True, True, True, False, False, False, False, False, False])
두 numpy array의 크기가 동일할 때 element 비교 결과를 array 형태로 반환합니다.
test_a = np.array([1, 3, 0], float)
test_b = np.array([5, 2, 1], float)
>>> test_a > test_b
array([False, True, False])
1) All, Any : Array의 데이터 전부(and) 또는 일부(or)가 조건에 만족할 때 반환
>>> np.any(a>5), np.any(a<0) # any -> 하나라도 조건에 만족한다면 true
(True, False)
>>> np.all(a>5), np.all(a<10) # all -> 모두가 조건에 만족한다면 true
(False, True)
2) logical_and, logical_not, logical_or : 조건들의 and, not, or에 맞춰 array 반환
- logical_and (a는 np.arange(10))
>>> np.logical_and(a > 0, a < 3) # and 조건의 condition
array([False, True, True, False, False, False, False, False, False, False])
- logical_not
>>> b = np.array([True, False, True], bool)
>>> np.logical_not(b)
array([False, True, False])
- logical_or
>>> c = np.array([False, True, False], bool)
>>> np.logical_or(b, c) # OR 조건의 condition
array([ True, True, True])
3) np.where
- parameter 1개 : condition에 따라 index값 반환
>>> np.where(a > 5)
(array([6, 7, 8, 9], dtype=int64),) # 조건에 맞는 index값 반환
- parameter 3개 : condition에 따라 지정해놓은 True, False 값 반환
>>> np.where(a > 5, 3, 2) # where(condition, TRUE, FALSE)
array([2, 2, 2, 2, 2, 2, 3, 3, 3, 3]) # 2는 False, 3은 True
4) argmax, argmin : array내의 최대값 또는 최소값의 index 반환
>>> a = np.array([1, 2, 4, 5, 8, 78, 23, 3])
>>> np.argmax(a), np.argmin(a) # 5번째에 최대값 78과 0번째에 최소값 1이 존재
(5, 0)
axis를 사용하면 해당 축 기준의 argmax, argmin을 구할 수 있습니다.(array 형태로 반환)
>>> a = np.array([[1, 2, 4, 7], [9, 88, 6, 45], [9, 76, 3, 4]])
>>> np.argmax(a, axis=1), np.argmin(a, axis=0)
(array([3, 1, 1], dtype=int64) # 7, 88, 76
, array([0, 0, 2, 2], dtype=int64)) # 1, 2, 3, 4
argsort는 sort를 index값으로 정렬할 수 있는 명령어입니다.
>>> a.argsort()[::-1]
array([5, 6, 4, 3, 2, 7, 1, 0], dtype=int64)
8️⃣ boolean & fancy index
1) boolean index : boolean 수식을 indexing에서 사용
아래 boolean 수식(test_array <3)을 indexing(test_array [condition]) 방법으로 사용 가능합니다.
>>> test_array = np.array([1, 4, 0, 2, 3, 8, 9, 7], float)
>>> condition = test_array < 3
>>> test_array[condition]
array([1., 0., 2.])
2) fancy index : array 값을 다른 array의 index로 사용
b의 array값을 a의 index로 사용하는 것이 가능합니다.
a = np.array([2, 4, 6, 8], float)
b = np.array([0, 0, 1, 3, 2, 1], int)
>>> a[b]
array([2., 2., 4., 8. 6., 4.])
또한 matrix 형태의 데이터도 가능합니다.
a = np.array([[1, 4], [9, 16]], float)
b = np.array([0, 0, 1, 1, 0], int)
c = np.array([0, 1, 1, 1, 1], int)
>>> a[b, c] # b를 row index, c를 column index로 변환하여 표시함
array([ 1., 4., 16., 16., 4.])
9️⃣ Numpy data I/O
Numpy의 data i/o는 text type의 데이터를 읽고 저장하는 것이 가능합니다.
loadtxt()와 savetxt()를 사용해서 데이터를 읽고 저장합니다.
>>> a = np.loadtxt("./populations.txt", delimiter="\t")
>>> a
array([[ 1900., 30000., 4000., 48300.],
[ 1901., 47200., 6100., 48200.],
[ 1902., 70200., 9800., 41500.],
[ 1903., 77400., 35200., 38200.],
[ 1904., 36300., 59400., 40600.],
[ 1905., 20600., 41700., 39800.],
[ 1906., 18100., 19000., 38600.],
[ 1907., 21400., 13000., 42300.],
[ 1908., 22000., 8300., 44500.],
[ 1909., 25400., 9100., 42100.],
[ 1910., 27100., 7400., 46000.],
[ 1911., 40300., 8000., 46800.],
[ 1912., 57000., 12300., 43800.],
[ 1913., 76600., 19500., 40900.],
[ 1914., 52300., 45700., 39400.],
[ 1915., 19500., 51100., 39000.],
[ 1916., 11200., 29700., 36700.],
[ 1917., 7600., 15800., 41800.],
[ 1918., 14600., 9700., 43300.],
[ 1919., 16200., 10100., 41300.],
[ 1920., 24700., 8600., 47300.]])
>>> np.savetxt("int_data.csv", a_int, fmt="%.2e", delimiter=",") # fmt는 저장할 format형식을 정함
또는 .npy 형태로 읽고 저장할 수 있습니다.
>>> np.save("npy_test", arr=a_int)
>>> npy_array = np.load(file="npy_test.npy")
'부스트캠프 AI 테크 U stage > 이론' 카테고리의 다른 글
[07] 경사하강법 (0) | 2021.01.26 |
---|---|
[06-1] 벡터와 행렬 with Python Numpy (0) | 2021.01.25 |
[05] Python Exception/File/Log /data Handling (0) | 2021.01.22 |
[04-1] Python 정규 표현식(Regular Expression) (0) | 2021.01.22 |
[04] Python의 OOP (객체 지향 프로그래밍) 와 module (모듈) (0) | 2021.01.21 |