[Numpy] Numpy 기초
- Python Library 중 하나인 Numpy에 대한 기초 정리이다.
- Numpy는 대량의 데이터를 처리하는데 처리 속도가 빨라 데이터 분석에서 많이 활용되고 있다.
Numpy
- Numerical Python의 줄임말
- 빠른 수치 계산을 위해 C언어로 만들어진 Python 라이브러리
- 백터와 행렬 연산에 매우 편리한 기능들을 제공
- 데이터분석용 라이브러리인
Pandas
와Matplotlib
의 기반으로 사용되기도 함 - Numpy는 np.array 함수를 활용하여 배열을 생성함
- Numpy는 하나의 데이터 type 만 배열에 넣을 수 있음 -> List와 가장 큰 차이점
1. 라이브러리 불러오기
- Numpy 라이브러리는 일반적으로 np 별칭을 붙여 불러온다.
1
import numpy as np
2. 배열 만들기
- 편의를 위해 Numpy 배열을 그냥 배열이라고 부르자.
용어 정의
[용어]
- axis: 배열의 각 축
- rank: 축의 개수
- shape: 축의 길이, 배열의 크기
[3 x 4 배열의 경우]
- axis 0 과 axis 1 을 갖는 2차원 배열
- rank 2 array
- shape는 (3, 4)
배열 만들기
np.array()
함수를 사용해서 배열을 만듦.- 리스트로부터 배열을 만들거나, 머신러닝 관련 함수 결과값이 배열이 됨.
1
2
3
4
5
6
7
8
9
# 1차원 리스트
a = [1, 2, 3, 4, 5]
# 배열로 변환
b = np.array(a)
# 확인
print('list :', a)
print('np.array :', b)
1
2
list : [1, 2, 3, 4, 5]
np.array : [1 2 3 4 5]
1
2
3
4
5
6
7
8
a2 = [[1.5, 2.5, 3.2],
[4.2, 5.7, 6.4]]
# 배열로 변환
b2 = np.array(a2)
# 확인
print(b2)
1
2
[[1.5 2.5 3.2]
[4.2 5.7 6.4]]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3차원 리스트
# a3 = [[[1, 3, 1], [4, 7, 6], [8, 3, 4]], [[6, 2, 4], [8, 1, 5], [3, 5, 9]]]
a3 = [[[1, 3, 1],
[4, 7, 6],
[8, 3, 4]],
[[6, 2, 4],
[8, 1, 5],
[3, 5, 9]]]
# 배열로 변환
b3 = np.array(a3)
# 확인
print(b3)
1
2
3
4
5
6
7
[[[1 3 1]
[4 7 6]
[8 3 4]]
[[6 2 4]
[8 1 5]
[3 5 9]]]
Create Functions
1) arange
- array의 범위를 지정하여, 값의 List를 생성하는 명령어
1
np.arange(10)
1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
1
2
# (시작, 끝, step) step에 floating point도 표시가능
np.arange(0, 5, 0.5)
1
array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])
1
np.arange(30).reshape(5,6)
1
2
3
4
5
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]])
2) zeros
- 0으로 가득찬 배열 생성
1
np.zeros(shape=(10,), dtype=np.int8)
1
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int8)
1
2
# 2 by 5 - zero matrix 생성
np.zeros((2,5))
1
2
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
3) ones
- 1로 가득찬 배열 생성
np.ones(shape, dtype, order)
1
np.ones(shape=(10,), dtype=np.int8)
1
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int8)
1
np.ones((2,5))
1
2
array([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
4) empty
- shape만 주어지고 비어있는 배열 생성
- memory initialization 이 되지 않음
1
np.empty(shape=(10,), dtype=np.int8)
1
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int8)
1
np.empty((3,5))
1
2
3
4
5
6
array([[0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000],
[0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000],
[0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 1.02187024e+295]])
5) something_like
- 기존 배열의 shape 크기 만큼 1, 0 또는 empty array를 반환
1
2
test_matrix = np.arange(30).reshape(5,6)
np.ones_like(test_matrix)
1
2
3
4
5
array([[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1]])
6) identity
- 단위 행렬 (i 행렬)을 생성함
1
np.identity(n=3, dtype=np.int8)
1
2
3
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]], dtype=int8)
1
np.identity(5)
1
2
3
4
5
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.]])
7) eye
- 대각선이 1인 행렬, k값의 시작 index의 변경이 가능
1
np.eye(N=3, M=5, dtype=np.int8)
1
2
3
array([[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0]], dtype=int8)
1
np.eye(3)
1
2
3
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
1
2
# k -> start index
np.eye(3, 5, k=2)
1
2
3
array([[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
8) diag
- 대각 행렬의 값을 추출함
1
2
matrix = np.arange(9).reshape(3,3)
np.diag(matrix)
1
array([0, 4, 8])
1
np.diag(matrix, k=1)
1
array([1, 5])
9) Random Sampling
- 데이터 분포에 따른 sampling으로 array를 생성
1
2
# 균등분포
np.random.uniform(0,1,10).reshape(2,5)
1
2
array([[0.79399847, 0.78695637, 0.20878559, 0.68880039, 0.75485172],
[0.61325652, 0.95731992, 0.51921851, 0.79268682, 0.8922863 ]])
1
2
# 정규분포
np.random.normal(0,1,10).reshape(2,5)
1
2
array([[ 0.15096311, 0.7967732 , -0.25318434, 0.73347587, 2.8557428 ],
[ 0.9828345 , 1.19771688, -1.66174886, -1.10692387, -0.29010521]])
배열 정보 확인
- ndim : 배열의 차원을 반환함 (number of dimension)
- shape : 배열의 object의 dimension 구성을 반환함
- dtype : 배열의 data type을 반환함
- size : data의 개수를 반환함
Axis 0의 의미
- array.shape 의 첫 번째
- 분석단위를 구성
- 분석 단위 개수를 의미
1
2
3
print(b.ndim)
print(b2.ndim)
print(b3.ndim)
1
2
3
1
2
3
1
2
3
print(b.shape)
print(b2.shape)
print(b3.shape)
1
2
3
(5,)
(2, 3)
(2, 3, 3)
1
2
3
print(b.dtype)
print(b2.dtype)
print(b3.dtype)
1
2
3
int32
float64
int32
1
2
3
print(b.size)
print(b2.size)
print(b3.size)
1
2
3
5
6
18
Reshape
- 다양한 형태(Shape)로 변환
- 배열에 포함된 요소가 사라지지 않는 형태라면 자유롭게 변환 가능
- 배열의 Size만 같다면 다차원으로 자유롭게 변환 가능
1
2
3
4
5
6
7
8
9
# (2, 3) 형태의 2차원 배열 만들기
a = np.array([[1, 2, 3],
[4, 5, 6]])
# (3, 2) 형태의 배열로 Reshape
b = a.reshape(3, 2)
# 확인
print(b)
1
2
3
[[1 2]
[3 4]
[5 6]]
1
2
3
4
5
# 1차원 배열로 Reshape
c = a.reshape(6)
# 확인
print(c)
1
[1 2 3 4 5 6]
-1의 편리성
- (m, -1) 또는 (-1, n) 처럼 사용해 한 쪽만 지정할 수 있음
- -1의 자리는 자동으로 설정 해주는 것임.
1
2
3
4
5
6
7
8
9
10
11
12
# (2, 6) 형태의 2차원 배열 만들기
a = np.array([[1, 2, 3, 4, 5, 6],
[7, 8, 9, 10, 11, 12]])
# reshape(m, -1)
print(a.reshape(1, -1), end='\n----------\n')
print(a.reshape(4, -1), end='\n----------\n')
# reshape(-1, m, n)
print(a.reshape(-1, 2, 3), end='\n\n')
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]]
----------
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
Flatten
- 다차원 배열을 1차원 배열로 변환
1
2
test_matrix = [[[1,2,3,4],[1,2,5,7]], [[1,2,3,4],[1,2,5,8]]]
np.array(test_matrix).flatten()
1
array([1, 2, 3, 4, 1, 2, 5, 7, 1, 2, 3, 4, 1, 2, 5, 8])
3. 배열 인덱싱과 슬라이싱
인덱싱 (Indexing)
- array[행, 열] 형태로 특정 위치의 요소를 조회
- 열은 생략가능
- 행과 열에는
- 값, 단일 인덱스. ex) arr[2, 3]
- 값, 여러 인덱스. ex) arr[[list], [list]]
- 범위, 슬라이싱. ex) arr[1:5, 2:]
1) 요소 조회
1
2
3
4
5
6
7
# (3, 3) 형태의 2차원 배열 만들기
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 첫 번째 행, 두 번째 열 요소 조회
print(a[0, 1])
1
2
2) 행 조회
1
2
3
# 첫 번째, 두 번째 행 조회
# print(a[[0, 1], :])
print(a[[0, 1]])
1
2
[[1 2 3]
[4 5 6]]
3) 열 조회
1
2
# 첫 번째, 두 번째 열 조회
print(a[:, [0, 1]])
1
2
3
[[1 2]
[4 5]
[7 8]]
4) 행, 열 조회
1
2
# 두 번째 행 두 번째 열의 요소 조회
print(a[[1], [1]])
1
[5]
1
2
# 세 번째 행 두 번째 열의 요소 조회
print(a[[2], [1]])
1
[8]
슬라이싱 (Slicing)
- array[행1:행N, 열1:열N]의 형태로 지정해 그 위치의 요소를 조회
- 조회 결과는 2차원 배열이 됨
- 마지막 범위 값은 대상에 포함되지 않음
1
2
3
4
5
6
7
8
# (3, 3) 형태의 2차원 배열 만들기
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 첫 번째 ~ 두 번째 행 조회
# print(a[0:2, :])
print(a[0:2])
1
2
[[1 2 3]
[4 5 6]]
1
2
# 첫 번째 행, 첫 번째 ~ 두 번째 열 조회
print(a[0, 0:2])
1
[1 2]
1
2
# 첫 번째 ~ 세 번째 행, 두 번째 ~ 세 번째 열 조회
print(a[0:3, 1:3])
1
2
3
[[2 3]
[5 6]
[8 9]]
1
2
# 두 번째 ~ 끝 행, 두 번째 ~ 끝 열 조회
print(a[1:, 1:])
1
2
[[5 6]
[8 9]]
조건 조회
- 조건에 맞는 요소를 선택하는 방식이며,
boolean index
라고 부름 - 조회 결과는 1차원 배열이 됨
1
2
3
4
5
6
# 2차원 배열 만들기
score= np.array([[78, 91, 84, 89, 93, 65],
[82, 87, 96, 79, 91, 73]])
# 요소 중에서 90 이상인 것만 조회
print(score[score >= 90])
1
[91 93 96 91]
- 검색 조건을 변수로 선언해 사용할 수 있음
1
2
3
# 요소 중에서 90 이상인 것만 조회
condition = score >= 90
print(score[condition])
1
[91 93 96 91]
1
score >= 90
1
2
array([[False, True, False, False, True, False],
[False, False, True, False, True, False]])
1
2
# 모든 요소 중에서 90 이상 95 미만인 것만 조회
print(score[(score >= 90) & (score <= 95)])
1
[91 93 91]
Fancy index
- array를 index value로 사용해서 값을 추출하는 방법
1
2
3
a = np.array([2, 4, 6, 8])
b = np.array([0, 0 ,1, 3, 2, 1], int) # 반드시 integer로 선언
a[b]
1
array([2, 2, 4, 8, 6, 4])
1
a.take(b)
1
array([2, 2, 4, 8, 6, 4])
- Matrix 형태의 데이터도 가능 (많이 쓰지 않음)
1
2
3
4
a = np.array([[1,4],[9, 16]])
b = np.array([0,0,1,1,0], int)
c = np.array([0,1,1,0,1], int)
a[b,c]
1
array([ 1, 4, 16, 9, 4])
4. 배열 연산
- Numpy는 배열간의 기본적인 사칙 연산을 지원함
- Element-wise Operations : 배열간 shape이 같을 때 일어나는 연산 (같은 위치에 있는 값들끼리의 연산)
1
2
3
4
5
6
7
# 두 개의 (2, 2) 형태의 2차원 배열 만들기
x = np.array([[1, 2], [3, 4]])
y = np.array([[5, 6], [7, 8]])
# 확인
print(x)
print(y)
1
2
3
4
[[1 2]
[3 4]]
[[5 6]
[7 8]]
배열 더하기
+
또는np.add()
함수를 사용
1
2
3
4
5
# 배열 더하기
print(x + y)
# 또는
print(np.add(x, y))
1
2
3
4
[[ 6 8]
[10 12]]
[[ 6 8]
[10 12]]
배열 빼기
-
또는np.subtract()
함수를 사용
1
2
3
4
5
# 배열 빼기
print(x - y)
# 또는
print(np.subtract(x, y))
1
2
3
4
[[-4 -4]
[-4 -4]]
[[-4 -4]
[-4 -4]]
배열 곱하기
*
또는np.multiply()
함수를 사용
1
2
3
4
5
# 배열 곱하기
print(x * y)
# 또는
print(np.multiply(x, y))
1
2
3
4
[[ 5 12]
[21 32]]
[[ 5 12]
[21 32]]
배열 나누기
/
또는np.divide()
함수를 사용
1
2
3
4
5
# 배열 나누기
print(x / y)
# 또는
print(np.divide(x, y))
1
2
3
4
[[0.2 0.33333333]
[0.42857143 0.5 ]]
[[0.2 0.33333333]
[0.42857143 0.5 ]]
배열 제곱
**
또는np.power()
함수를 사용
1
2
3
4
5
# 배열 y 제곱
print(x ** y)
# 또는
print(np.power(x, y))
1
2
3
4
[[ 1 64]
[ 2187 65536]]
[[ 1 64]
[ 2187 65536]]
1
2
# 배열 제곱
print(x ** 2)
1
2
[[ 1 4]
[ 9 16]]
배열 집계
np.sum()
혹은array.sum()
- axis = 0 : 열 기준 집계
- axis = 1 : 행 기준 집계
- 생략하면 : 전체 집계
- 동일한 형태로 사용 가능한 함수 :
np.max(), np.min(), np.mean(), np.std()
1
2
3
4
5
6
7
8
9
10
11
12
# array를 생성합니다.
a = np.array([[1,5,7],[2,3,8]])
print(a, end='\n\n')
# 전체 집계
print(np.sum(a), end='\n\n')
# 열기준 집계
print(np.sum(a, axis = 0), end='\n\n')
# 행기준 집계
print(np.sum(a, axis = 1))
1
2
3
4
5
6
7
8
[[1 5 7]
[2 3 8]]
26
[ 3 8 15]
[13 13]
Dot Product
- matrix의 기본 연산
- dot 함수 사용
1
2
3
a = np.arange(1,7).reshape(2,3)
b = np.arange(7,13).reshape(3,2)
a.dot(b)
1
2
array([[ 58, 64],
[139, 154]])
Transpose
- transpose 또는 T attribute 사용
1
2
a = np.arange(1,7).reshape(2,3)
a
1
2
array([[1, 2, 3],
[4, 5, 6]])
1
a.T
1
2
3
array([[1, 4],
[2, 5],
[3, 6]])
Broadcasting
- shape이 다른 배열 간 연산을 자동으로 지원하는 기능
- scalar - vector 외에도 vector - matrix 간의 연산도 지원
1
2
a + 3
# a - 2, a * 4, a / 2, a // 0.2, a ** 3 등등
1
2
array([[4, 5, 6],
[7, 8, 9]])
1
2
3
test_matrix = np.arange(1,13).reshape(4,3)
test_vector = np.arange(10,40,10)
test_matrix + test_vector
1
2
3
4
array([[11, 22, 33],
[14, 25, 36],
[17, 28, 39],
[20, 31, 42]])
Operation Functions
1) Concatenate
- 배열을 합치는 함수
- vstack : 세로로 합치기
- hstack : 가로로 합치기
- concatenate : axis=0 -> vstack, axis=1 -> hstack
1
2
3
4
a = np.array([1,2,3])
b = np.array([5,7,8])
c = np.vstack((a,b))
c
1
2
array([[1, 2, 3],
[5, 7, 8]])
1
2
3
4
a = np.array([[1],[2],[3]])
b = np.array([[5],[7],[8]])
c = np.hstack((a,b))
c
1
2
3
array([[1, 5],
[2, 7],
[3, 8]])
1
2
3
4
a = np.array([[1, 2, 3]])
b = np.array([[5, 7, 8]])
c = np.concatenate((a,b), axis=0)
c
1
2
array([[1, 2, 3],
[5, 7, 8]])
1
2
3
4
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
c = np.concatenate((a,b.T), axis=1)
c
1
2
array([[1, 2, 5],
[3, 4, 6]])
5. Comparisons
All & Any
- 배열의 데이터 전부(and) 또는 일부(or)가 조건에 만족 여부 반환
1
2
a = np.arange(10)
np.all(a>5), np.all(a<10)
1
(False, True)
1
np.any(a>5), np.any(a<0)
1
(True, False)
1
a<0
1
2
array([False, False, False, False, False, False, False, False, False,
False])
- Numpy 는 배열의 크기가 동일 할 때 element간 비교의 결과를 Boolean type으로 반환하여 돌려줌
1
2
3
test_a = np.array([1, 3, 0], float)
test_b = np.array([5, 2, 1], float)
test_a > test_b
1
array([False, True, False])
np.where (중요!)
- np.where(condition, TRUE, FALSE)
1
np.where(test_a > 0, 3, 2)
1
array([3, 3, 2])
1
np.where(a > 5)
1
(array([6, 7, 8, 9], dtype=int64),)
1
2
a = np.array([1,np.NaN, np.Inf], float)
np.isnan(a)
1
array([False, True, False])
1
np.isfinite(a)
1
array([ True, False, False])
argmax & argmin (중요!)
- 배열 내 최대값 또는 최소값의 index를 반환
- axis 기반의 반환
- axis = 0 : 행 방향 최대, 최소값의 index
- axis = 1 : 열 방향 최대, 최소값의 index
1
2
a = np.array([1,2,4,5,8,78,23,3])
np.argmax(a), np.argmin(a)
1
(5, 0)
1
2
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)
1
(array([3, 1, 1], dtype=int64), array([0, 0, 2, 2], dtype=int64))
6. numpy data i/o
loadtxt & savetxt
- Text type의 데이터를 읽고, 저장하는 기능
1
2
a = np.loadtxt("./test.txt")
a
1
2
3
4
array([[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.],
[13., 14., 15., 16.]])
1
2
a_int = a.astype(int)
a_int
1
2
3
4
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
1
np.savetxt('test.csv',a_int, fmt='%d', delimiter=",")
numpy object - npy
- numpy object (pickle) 형태로 데이터를 저장하고 불러옴
- binary 파일 형태로 저장함
1
np.save("npy_test.npy", arr=a_int)
1
2
npy_array = np.load(file="npy_test.npy")
npy_array
1
2
3
4
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
This post is licensed under CC BY 4.0 by the author.