[Python][Numpy] 배열 사용(Array manipulation)
이번에는 Numpy(Numerical Python)
배열을 조작하는 내용을 주로 공부해 보겠습니다.
Numpy 홈페이지 : numpy.org
Array manipulation routines : API 참조
numpy 조작
배열 정보
배열 정보 확인을 위해서 아래 배열 함수를 작성하겠습니다.
항목 | 설명 |
---|---|
ndim | 배열 차원 |
shape | 배열 shape |
dtype | 배열 데이터 타입 |
size | 배열 요소 수 |
itemsize | 배열 각 맴버의 바이트 크기 |
nbytes | 배열의 요소가 소비 한 총 바이트 |
strides | 배열을 탐색 할 때 각 차원에서 단계별로 이동할 바이트 수 |
def ainfo(array):
print("ndim : ", array.ndim)
print("shape : ", array.shape)
print("dytpe : ", array.dtype)
print("size : ", array.size)
print("itemsize : ", array.itemsize)
print("nbytes : ", array.nbytes)
print("strides : ", array.strides)
print(array)
ainfo(np.array([1,2,3,4,5]))
# ndim : 1
# shape : (5,)
# dytpe : int32
# size : 5
# itemsize : 4
# nbytes : 20
# strides : (4,)
# [1 2 3 4 5]
기본 인덱싱
a1 = np.array([1,2,3,4,5]);
a2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
a3 = np.array( [
[[1,2,3],[4,5,6],[7,8,9]],
[[1,2,3],[4,5,6],[7,8,9]],
[[1,2,3],[4,5,6],[7,8,9]]
])
print(a1) # [1 2 3 4 5]
print(a1[0]) # 1
print(a1[1]) # 2
print(a1[2]) # 3
print(a1[-1]) # 4
print(a1[-2]) # 5
print(a2)
print(a2[0,0]) # 1
print(a2[0,2]) # 3
print(a2[1,1]) # 5
print(a2[2,-1]) # 9
print(a3)
print(a3[0,0,0]) # 1
print(a3[1,1,1]) # 5
print(a3[2,-1,-1]) # 9
Boolean Indexing
True
값인 인덱스의 배열을 생성 합니다.
print(a1)
bi = [False, True, True, False, True]
print(bi)
print(a1[bi])
#[1 2 3 4 5]
#[False, True, True, False, True]
#[2 3 5]
print(a2)
bi = np.random.randint(0,2, (3,3), dtype=bool)
print(bi)
print(a2[bi])
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
# [[ True True False]
# [ True False True]
# [False False True]]
# [1 2 4 6 9] or random으로 선택된 배열이 출력됨
Fancy Indedxing
index 번호
에 해당하는 데이터로 배열을 생성 합니다.
print(a1) # [1 2 3 4 5]
print([a1[0],a1[2]]) # [1, 3]
index = [0,2]
print(a1[index]) # [1 3]
#2차원으로 전달할 경우, 출력도 2차원으로 반환됨
index = np.array([[0,1],[2,0]])
print(index)
# [[0 1]
# [2 0]]
print(a1[index])
# [[1 2]
# [3 1]]
# 복합으로 인덱스를 만들어서 제공할 경우에도 출력됨
print(a2)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
row = np.array([0,2])
col = np.array([1,2])
print(a2[row, col]) # [2 9]
#위 (0,1) (2,2) 에 해당하는 값이 [2 9] 출력됨
print(a2[row, :])
# [[1 2 3]
# [7 8 9]]
print(a2[:, col])
# [[2 3]
# [5 6]
# [8 9]]
print(a2[row, 1])
# [2 8]
print(a2[2, col])
# [8 9]
print(a2[row, 1:])
# [[2 3]
# [8 9]]
print(a2[1:, col])
# [[5 6]
# [8 9]]
Fancy Indedxing 은 배열의 재정의 뿐 아니라, 배열의 연산에도 사용될 수 있습니다.
a1 = np.array([1,2,3,4,5])
i = np.array([1,3,4])
a1[i] = 0
print(a1) # [1 0 3 0 0] i의 index 번호의 값이 0으로 초기화됨
a1[i] +=4 # i가 있는 index에 +4 가 된것을 확인함.
print(a1) # [1 4 3 4 4]
슬라이싱
list
형의 슬라이싱과 동일한 비슷한 형태로 제공합니다.
print(a1) #[1 2 3 4 5]
print(a1[0:2]) #[1 2]
print(a1[0:]) #[1 2 3 4 5]
print(a1[:1]) #[1]
print(a1[::2]) #[1 3 5]
print(a1[::-1]) #[5 4 3 2 1]
print(a1[:]) #[1 2 3 4 5]
print(a2)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
print(a2[1]) # [4 5 6]
print(a2[1, :]) # [4 5 6]
print(a2[:2,:2])
# [[1 2]
# [4 5]
print(a2[1:,::-1])
# [[6 5 4]
# [9 8 7]]
print(a2[::-1,::-1])
# [[9 8 7]
# [6 5 4]
# [3 2 1]]
a2_sub = a2[:2,:2];
print(a2_sub)
# [[1 2]
# [4 5]]
a2_sub[:,1] = 0 # 값을 변경함.
print(a2_sub)
# [[1 0]
# [4 0]]
print(a2) #numpy의 slicing 했을떄 원본도 값이 변경됨
# [[1 0 3]
# [4 0 6]
# [7 8 9]]
# a2_sub = a2[:2,:2].copy() 로 복사본 사용시 원본과 분리됨.
numpy.insert
배열에 데이터를 삽입을 학습하겠습니다.
numpy.insert(arr, obj, values, axis=None)
API 참조
데이터를 추가할때 axis
을 추가할 수 있는데, axis=0
는 행
, axis=1
은 열
으로 인식합니다.
print(a1) # [1 2 3 4 5]
b1 = np.insert(a1, 0, 10) #0번째 10값을 추가해서 b1 새로운 array를 반환함
print(b1) # [10 1 2 3 4 5]
print(a1) # [1 2 3 4 5]
print(a2)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
b2 = np.insert(a2, 1, 10, axis = 0)
print(b2)
# [[ 1 2 3]
# [10 10 10] <- 1번 째 10 값을 axis=0(행) 단위로 추가함
# [ 4 5 6]
# [ 7 8 9]]
b2 = np.insert(a2, 1, 10, axis = 1)
print(b2)
# <- 1번 째 10 값을 axis=1(열) 단위로 추가함
# [[ 1 10 2 3]
# [ 4 10 5 6]
# [ 7 10 8 9]]
numpy.delete
배열에 데이터를 삽입을 학습하겠습니다.
numpy.delete(arr, obj, axis=None)
API 참조
데이터를 삭제할때 axis
을 추가할 수 있는데, axis=0
는 행
, axis=1
은 열
으로 인식합니다.
# 1차원에서 배열 삭제
a1 = np.array([1,2,3,4,5])
print(a1) # [1 2 3 4 5]
b1 = np.delete(a1, 1)
print(b1) # [1 3 4 5]
print(a1) # [1 2 3 4 5] 원본 배열은 값을 유지함
# 2 차원에서 배열 삭제
print(a2)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
b3 = np.delete(a2, 1, 0) # axis = 0
print(b3)
# 1번 행이 없어짐
# [[1 2 3]
# [7 8 9]]
print(a2)
b4 = np.delete(a2, 1, 1) # axis = 1
# [[1 3]
# [4 6]
# [7 9]]
numpy.ndarray.T
ndarray.T
로 데이터 형태를 피벗을 합니다.
# 1차원은 변화 없음
a1 = np.array([1,2,3,4,5])
print(a1.T)
# [1 2 3 4 5]
# 2차원
a2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a2)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
print(a2.T) #행열이 전환,
# [[1 4 7]
# [2 5 8]
# [3 6 9]]
# 3차원
a3 = np.array( [
[[1,2,3],[4,5,6],[7,8,9]],
[[1,2,3],[4,5,6],[7,8,9]],
[[1,2,3],[4,5,6],[7,8,9]]
])
print(a3.T)
# [[[1 1 1]
# [4 4 4]
# [7 7 7]]
# [[2 2 2]
# [5 5 5]
# [8 8 8]]
# [[3 3 3]
# [6 6 6]
# [9 9 9]]]
# [[[1 1 1][4 4 4][7 7 7]]
# [[2 2 2][5 5 5][8 8 8]]
# [[3 3 3][6 6 6][9 9 9]]]
a4 = a3.T.copy()
print(a4.T)
# [[[1 2 3]
# [4 5 6]
# [7 8 9]]
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
# [[1 2 3]
# [4 5 6]
# [7 8 9]]]
numpy.reshape
배열의 shape 을 재 구조화 합니다.
numpy.reshape(a, newshape, order='C')[source]
API 참조
n1 = np.arange(1, 10)
print(n1) # [1 2 3 4 5 6 7 8 9]
print(n1.reshape(3,3))
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
# 사이즈가 맞지 않는 경우, 다음 에러를 발생 시킵니다.
n2 = np.arange(1, 10)
print(n2.reshape(5,5))
------------------------------------------------
ValueError Traceback (most recent call last)
Input In [119], in <cell line: 2>()
1 n2 = np.arange(1, 10)
----> 2 print(n2.reshape(5,5))
ValueError: cannot reshape array of size 9 into shape (5,5)
numpy.append
배열의 병합하는 역할을 진행 합니다.
numpy.append(arr, values, axis=None)
API 참조
a2 = np.arange(1,10).reshape(3,3)
# print(a2)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
b2 = np.arange(10,19).reshape(3,3)
print(b2)
# [[10 11 12]
# [13 14 15]
# [16 17 18]]
c2 = np.append(a2, b2)
print(c2) #1차원으로 결과 반환
#[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18]
# 축을 지정하여 추가함.
c2 = np.append(a2, b2, axis=0) # 행단위
print(c2)
# [[ 1 2 3]
# [ 4 5 6]
# [ 7 8 9]
# [10 11 12]
# [13 14 15]
# [16 17 18]]
c2 = np.append(a2, b2, axis=1)
print(c2)
# [[ 1 2 3 10 11 12]
# [ 4 5 6 13 14 15]
# [ 7 8 9 16 17 18]]
numpy.stack
nparray의 축을 선택 하여 누적 시킵니다.
numpy.stack(arrays, axis=0, out=None)
API 참조
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
np.stack((a, b)) # np.stack((a, b), axis=0) 과 동일
# array([[1, 2, 3],
# [4, 5, 6]])
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
np.stack((a, b),axis=1)
# array([[1, 4],
# [2, 5],
# [3, 6]])
numpy.vstack
nparray의 vertical 축의 병합 입니다.
np.append(a2, b2, axis=0)
동일 결과를 나타납니다.
API 참조
np.vstack((a2,b2))
# array([[ 1, 2, 3],
# [ 4, 5, 6],
# [ 7, 8, 9],
# [10, 11, 12],
# [13, 14, 15],
# [16, 17, 18]])
numpy.hstack
nparray의 horizontal 축의 병합 입니다.
np.append(a2, b2, axis=1)
동일 결과를 나타납니다.
API 참조
np.hstack((a2,b2))
# array([[ 1, 2, 3, 10, 11, 12],
# [ 4, 5, 6, 13, 14, 15],
# [ 7, 8, 9, 16, 17, 18]])
numpy.concatenate
nparray를 연결 합니다.
numpy.concatenate((a1, a2, ...), axis=0, out=None, dtype=None, casting="same_kind")
API 참조
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
np.concatenate((a, b), axis=0)
# array([[1, 2],
# [3, 4],
# [5, 6]])
np.concatenate((a, b), axis=None)
# array([1, 2, 3, 4, 5, 6])
np.concatenate((a, b.T), axis=1)
# array([[1, 2, 5],
# [3, 4, 6]])
# a + b.T
# [[1, 2], [[5],
# [3, 4]] [6]]
a1 = np.array([1,3,5])
b1 = np.array([2,4,6])
c1 = np.array([7,8,9])
np.concatenate([a1,b1,c1])
# array([1, 3, 5, 2, 4, 6, 7, 8, 9])
a2 = np.array([[1,2,3],[4,5,6]])
np.concatenate([a2,a2])
# array([[1, 2, 3],
# [4, 5, 6],
# [1, 2, 3],
# [4, 5, 6]])
np.concatenate([a2,a2], axis=1)
# array([[1, 2, 3, 1, 2, 3],
# [4, 5, 6, 4, 5, 6]])
np.concatenate([a2,a2], axis=0)
# array([[1, 2, 3],
# [4, 5, 6],
# [1, 2, 3],
# [4, 5, 6]])
numpy.vsplit
veritcal 기준으로 ndarrray를 분할 합니다.
numpy.vsplit(ary, indices_or_sections)
API 참조
a2 = np.arange(1,10).reshape(3,3)
print(a2)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
b2, b3 = np.vsplit(a2, [2])
print(b2)
# [[1 2 3]
# [4 5 6]]
print(b3)
# [[7 8 9]]
x = np.arange(16.0).reshape(4, 4)
# array([[ 0., 1., 2., 3.],
# [ 4., 5., 6., 7.],
# [ 8., 9., 10., 11.],
# [12., 13., 14., 15.]])
np.vsplit(x, 2)
# [array([[0., 1., 2., 3.],
# [4., 5., 6., 7.]]),
# array([[ 8., 9., 10., 11.],
# [12., 13., 14., 15.]])]
numpy.hsplit
Horizontal 기준으로 ndarrray를 분할 합니다.
numpy.hsplit(ary, indices_or_sections)
API 참조
a2 = np.arange(1,10).reshape(3,3)
print(a2)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
b2, b3 = np.hvsplit(a2, [2])
print(b2)
# [[1 2]
# [4 5]
# [7 8]]
print(b3)
# [[3]
# [6]
# [9]]
numpy.random
자료를 임의로 만들어야 할때 자주 사용되는 라이브러리 입니다.
numpy.random.rand
0~1의 균일분포 표준정규분포 난수를 생성하여 반환합니다.
random.rand(d0, d1, ..., dn)
API 참조
np.random.rand(5)
# array([0.42734205, 0.95354301, 0.80731892, 0.6908605 , 0.64658099])
np.random.rand(5,2)
# array([[0.85155709, 0.25876853],
# [0.63304735, 0.12171615],
# [0.11996824, 0.71999629],
# [0.45233059, 0.77861135],
# [0.43984419, 0.69105062]])
numpy.random.randn
평균0
, 표준편차 1
인 가우시안 표준 정규분포의 난수를 생성하여 반환합니다.
random.randn(d0, d1, ..., dn)
API 참조
np.random.randn(5)
# array([ 0.74225719, -0.39754649, 0.8966088 , 0.30346421, 0.71134092])
np.random.randn(5,2)
# array([[-0.76182035, -0.51200261],
# [ 0.51620442, 0.77368734],
# [-0.23963806, 0.53549214],
# [ 1.37556231, -0.87648979],
# [ 0.51587644, -0.93696996]])
numpy.random.randint
범위내 int 타입의 난수를 생성하여 반환합니다.
random.randint(low, high=None, size=None, dtype=int)
API 참조
np.random.randint(10) # 0~9 까지의 임의의 수 반환
np.random.randint(5, 10) # 5이상 ~ 10미만의 임의의 숫자
np.random.randint(10, size=5)
# array([5, 3, 9, 1, 0])
np.random.randint(5, size=(2, 4))
# array([[2, 2, 3, 4],
# [2, 4, 2, 4]])