수리수리연수리 코드얍

Numpy 함수 정리 본문

신나는 Python

Numpy 함수 정리

ydduri 2023. 1. 28. 09:26
목차

1. 초기화 함수
2. 배열 재구조화
3. 배열 크기 변경
4. 배열 추가
5. 배열 값 삽입
6. 배열 값 삭제
7. 배열 복사
8. 배열 값 탐색
9. 배열 병합
10. 배열 분할

1. 초기화 함수

  • np.zeros(10): 0으로 채워진 길이 10 배열 생성
  • np.ones((2, 3)): 1로 채워진 2*3 배열 생성
  • np.full((3, 3), 1.5): 1.5로 채워진 3*3 배열 생성
  • np.eye(3): 3*3 단위행렬 생성
np.eye(3)

# 결과
# array([[1., 0., 0.],
#        [0., 1., 0.],
#        [0., 0., 1.]])
  • np.zeros_like(a1): a1과 같은 shape의 배열 생성
a1 = np.array([1, 2, 3])
np.zeros_like(a1)

# 결과
# array([0, 0, 0])
  • np.random.random((3, 3)): 랜덤한 실수 뽑아 3*3 배열 생성
  • np.random.randint(0, 10, size=(3, 3)): 0부터 10까지 정수 중 랜덤하게 뽑아 3*3 배열 생성
  • np.random.normal(0, 1, size=(3, 3)): 평균 0, 표준편차 1인 정규분포를 따르도록 랜덤하게 뽑아 3*3 배열 생성

2. 배열 재구조화

  • .reshape(): 배열 형상 변경
n1 = np.arange(1, 10)
print(n1)
print(n1.reshape(3, 3))

# 결과
# [1 2 3 4 5 6 7 8 9]

# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]
  • newaxis: 새로운 축 추가
print(n1)
print(n1[np.newaxis, :5])
print(n1[:5, np.newaxis])

# 결과
# [1 2 3 4 5 6 7 8 9]

# [[1 2 3 4 5]]

# [[1]
#  [2]
#  [3]
#  [4]
#  [5]]
print(n1.shape)
print(n1[np.newaxis, :5].shape)
print(n1[:5, np.newaxis].shape)

# 결과
# (9,)
# (1, 5)
# (5, 1)

3. 배열 크기 변경

  • .resize(): 배열 크기 변경
n2 = np.random.randint(0, 10, (2, 5))
print(n2)
n2.resize((5, 2))
print(n2)

# 결과
# [[7 9 7 5 9]
#  [9 0 8 9 5]]

# [[7 9]
#  [7 5]
#  [9 9]
#  [0 8]
#  [9 5]]
  • 기존 배열보다 큰 사이즈로 resize를 해서 남는 공간이 생긴다면 0으로 채워보자!
### Method 1

n2.resize((5, 5), refcheck=False)
print(n2)

# Method 1 결과
# [[7 9 7 5 9]
#  [9 0 8 9 5]
#  [0 0 0 0 0]
#  [0 0 0 0 0]
#  [0 0 0 0 0]]
### Method 2

np.resize(n2, (5, 5))

# Method 2 결과
# array([[7, 9, 7, 5, 9],
#        [9, 0, 8, 9, 5],
#        [0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0]])
  • 기존 배열보다 작은 사이즈로 resize를 해서 포함되지 않는 값이 생길 경우 삭제해보자!
n2.resize((3, 3),refcheck=False)
print(n2)

# 결과
# [[7 9 7]
#  [5 9 9]
#  [0 8 9]]

4. 배열 추가

  • .append(): 배열의 끝에 값 추가, axis 지정하지 않으면 1차원 배열로 변환
a2 = np.arange(1, 10).reshape(3, 3)
print(a2)
b2 = np.arange(10, 19).reshape(3, 3)
print(b2)

# 결과
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

# [[10 11 12]
#  [13 14 15]
#  [16 17 18]]
c2 = np.append(a2, b2)
print(c2)

# 결과
# [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18]
  • axis = 0(행 방향, 행이 쌓이는 방향)을 추가하면?
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]]
  • axis = 1(열 방향, 열이 쌓이는 방향)을 추가하면?
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]]

5. 배열 값 삽입

  • .insert(): 배열의 특정 위치에 값 삽입, axis 지정하지 않으면 1차원 배열로 변환
  • ex) np.insert(a1, 0, 10): a1 배열의 0번째 자리에 10이라는 원소 삽입
a1 = np.array([1, 2, 3, 4, 5, 6]).reshape(2, 3)
print(a1)

b1 = np.insert(a1, 0, 10)
print(b1)

c1 = np.insert(a1, 2, 10)
print(c1)

# 결과
# [[1 2 3]
#  [4 5 6]]

# [10  1  2  3  4  5  6]

# [ 1  2 10  3  4  5  6]
  • axis = 0(행 방향, 행이 쌓이는 방향)을 지정하면?
  • 결과를 보면, b2는 a2의 1번째 행에 10으로 구성된 행이 추가된 것을 확인할 수 있다.
a2 = np.arange(1, 10).reshape(3, 3)
print(a2)

b2 = np.insert(a2, 1, 10, axis = 0)
print(b2)

# 결과
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

# [[ 1  2  3]
#  [10 10 10]
#  [ 4  5  6]
#  [ 7  8  9]]
  • axis = 1(열 방향, 열이 쌓이는 방향)을 지정하면?
  • 결과를 보면, c2는 a2의 1번째 열에 1, 2, 10으로 구성된 열이 추가된 것을 확인할 수 있다.
c2 = np.insert(a2, 1, [1,2,10], axis = 1)
print(c2)

# 결과
# [[ 1  1  2  3]
#  [ 4  2  5  6]
#  [ 7 10  8  9]]

6. 배열 값 삭제

  • .delete(): 배열의 특정 위치 값 삭제, axis 지정하지 않으면 1차원 배열로 변환
  • ex) np.delete(a1, 1): a1 배열의 1번째 값 삭제
a1 = np.array([1, 2, 3, 4, 5, 6]).reshape(2, 3)
print(a1)

b1 = np.delete(a1, 1)
print(b1)

# 결과
# [[1 2 3]
#  [4 5 6]]

# [1 3 4 5 6]
  • axis = 0(행 방향, 행이 쌓이는 방향)을 지정하면?
  • 결과를 보면, b2는 a2의 1번째 행이 삭제된 것을 확인할 수 있다.
a2 = np.arange(1, 10).reshape(3, 3)
print(a2)

b2 = np.delete(a2, 1, axis = 0)
print(b2)

# 결과
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

# [[1 2 3]
#  [7 8 9]]
  • axis = 1(열 방향, 열이 쌓이는 방향)을 지정하면?
  • 결과를 보면, c2는 a2의 1번째 열이 삭제된 것을 확인할 수 있다.
c2 = np.delete(a2, 1, axis = 1)
print(c2)

# 결과
# [[1 3]
#  [4 6]
#  [7 9]]

7. 배열 복사

  • .copy(): 배열이나 하위 배열 내의 값을 명시적으로 복사
  • 우선 copy를 하지 않았을 때를 먼저 살펴보자!
  • 아래와 같은 식으로 배열을 받아올 때, 받아온 배열이 원본 배열에 영향을 준다(동일한 메모리 위치 사용하기 때문).
  • 원본 배열 a2를 단순히 받아온 배열인 a2_sub를 변화시켰을 때, 원본 배열 a2도 함께 변한다.
a2 = np.arange(1, 10).reshape(3, 3)
print(a2)

a2_sub = a2[:2, :2]
print(a2_sub)

a2_sub[:, 1] = 0
print(a2_sub)

print(a2)

# 결과
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

# [[1 2]
#  [4 5]]

# [[1 0]
#  [4 0]]

# [[1 0 3]
#  [4 0 6]
#  [7 8 9]]
  • 이번엔 copy를 했을 때를 살펴보자!
  • copy한 배열인 a2_copy를 변화시키더라도 원본 배열인 a2는 영향을 받지 않는 것을 확인할 수 있다.
a2 = np.arange(1, 10).reshape(3, 3)
print(a2)

a2_copy = a2[:2, :2].copy()
print(a2_copy)

a2_copy[:, 1] = 1
print(a2_copy)

print(a2)

# 결과
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

# [[1 2]
#  [4 5]]
 
# [[1 1]
#  [4 1]]

# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

8. 배열 값 탐색

  • np.where(): 조건을 만족하는 인덱스 반환
a1 = np.arange(5, 15) 
print(a1)
print(np.where(a > 10))

# 결과
# [ 5  6  7  8  9 10 11 12 13 14]
# (array([6, 7, 8, 9]),)
  • np.unique(): 주어진 배열에서의 고유값 탐색
a2 = np.array([[2, 3, 4],
               [5, 4, 7],
               [4, 2, 3]])
unique_array = np.unique(a2, return_counts=True)
print(unique_array)

# 결과
# (array([2, 3, 4, 5, 7]), array([2, 2, 3, 1, 1]))

9. 배열 병합

  • np.concatenate(): 튜플이나 배열의 리스트를 인수로 받아 연결
### 1차원 배열 연결

a1 = np.array([1, 3, 5])
b1 = np.array([2, 4, 6])
np.concatenate([a1, b1])

# 결과
# array([1, 3, 5, 2, 4, 6])
### 2차원 배열 연결(axis 지정 없음)

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]])
### 2차원 배열 연결(axis = 0 지정)
# axis를 지정하지 않았을 때와 차이가 없음을 알 수 있다!

a2 = np.array([[1, 2, 3],
               [4, 5, 6]])
np.concatenate([a2, a2], axis = 0)

# 결과
# array([[1, 2, 3],
#        [4, 5, 6],
#        [1, 2, 3],
#        [4, 5, 6]])
### 2차원 배열 연결(axis = 1 지정)

a2 = np.array([[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.vstack(): 수직 스택(수직으로 쌓는다!)
  • np.concatenate()에서 axis를 지정하지 않거나 axis = 0으로 했을 때, 즉 행이 쌓이는 방향일 때와 같은 결과가 나온다.
np.vstack([a2, a2])

# 결과
# array([[1, 2, 3],
#        [4, 5, 6],
#        [1, 2, 3],
#        [4, 5, 6]])
  • np.hstack(): 수평 스택(수평하게 붙인다!)
  • np.concatenate()에서 axis = 1로 했을 때, 즉 열이 쌓이는 방향일 때와 같은 결과가 나온다.
np.hstack([a2, a2])

# 결과
# array([[1, 2, 3, 1, 2, 3],
#        [4, 5, 6, 4, 5, 6]])
  • np.dstack(): 깊이 스택
np.dstack([a2, a2])

# 결과
# array([[[1, 1],
#         [2, 2],
#         [3, 3]],

#        [[4, 4],
#         [5, 5],
#         [6, 6]]])
  • np.stack(): 새로운 차원으로 연결
np.stack([a2, a2])

# 결과
# array([[[1, 2, 3],
#         [4, 5, 6]],

#        [[1, 2, 3],
#         [4, 5, 6]]])

10. 배열 분할

  • np.split(): 배열 분할
a1 = np.arange(0, 10)
print(a1)

b1, c1 = np.split(a1, [5]) # 인덱스 5 기준으로 split
print(b1, c1)

b1, c1, d1, e1, f1 = np.split(a1, [2, 4, 6, 8])
print(b1, c1, d1, e1, f1)

# 결과
# [0 1 2 3 4 5 6 7 8 9]

# [0 1 2 3 4] [5 6 7 8 9]

# [0 1] [2 3] [4 5] [6 7] [8 9]
  • np.vsplit(): 수직 분할
a2 = np.arange(1, 10).reshape(3, 3)
print(a2)

b2, c2 = np.vsplit(a2, [2])
print(b2)
print(c2)

# 결과
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

# [[1 2 3]
#  [4 5 6]]

# [[7 8 9]]
  • np.hsplit(): 수평 분할
a2 = np.arange(1, 10).reshape(3,3)
print(a2)

b2, c2 = np.hsplit(a2, [2])
print(b2)
print(c2)

# 결과
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]

# [[1 2]
#  [4 5]
#  [7 8]]

# [[3]
#  [6]
#  [9]]
  • np.dsplit(): 깊이 분할
a3 = np.arange(1, 28).reshape(3, 3, 3)
print(a3)

b3, c3 = np.dsplit(a3, [2])
print(b3)
print(c3)

# 결과
# a3 --------------
# [[[ 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]]]

# b3 --------------
# [[[ 1  2]
#   [ 4  5]
#   [ 7  8]]

#  [[10 11]
#   [13 14]
#   [16 17]]

#  [[19 20]
#   [22 23]
#   [25 26]]]

# c3 --------------
# [[[ 3]
#   [ 6]
#   [ 9]]

#  [[12]
#   [15]
#   [18]]

#  [[21]
#   [24]
#   [27]]]
Comments