머신러닝

넘파이(NumPy) 2

haniru 2026. 1. 7. 21:42

1. 특수 배열 생성: zeros, ones, eye

배열을 초기화할 때 연산의 목적에 따라 적절한 함수를 선택해야 한다.

  • np.zeros((rows, cols)): 모든 요소가 0인 행렬. 초기화 후 값을 더해나가는 누적 연산의 베이스로 주로 사용한다.
  • np.ones((rows, cols)): 모든 요소가 1인 행렬. 곱셈의 항등원 역할을 하며, 특정 값을 전체에 곱해주기 전 기초 행렬로 사용한다.
  • np.eye(n) (Identity Matrix): 대각 성분만 1이고 나머지는 0인 단위 행렬이다. 선형대수에서 숫자 1과 같은 역할을 수행한다.

 

2. 로그 스케일과 logspace

  • np.logspace(start, stop, num): 로그 스케일로 등간격인 숫자를 생성한다.

3. 차원 변형: flatten vs reshape vs ravel

메모한 flatten과 reshape(-1)의 차이점에 대해 더 깊이 들어가면 성능 최적화에 도움이 된다.

  • flatten(): 항상 데이터를 복사(Copy)하여 새로운 1차원 배열을 만든다. 원본 배열의 값이 바뀌어도 영향을 받지 않지만, 메모리 사용량이 늘어난다.
  • reshape(-1): 가능하면 원본의 **뷰(View)**를 반환한다. 즉, 메모리를 새로 할당하지 않고 바라보는 방식만 바꾼다. 따라서 메모리 효율과 속도 면에서는 reshape나 ravel()이 유리할 때가 많다.
  • 복잡도: reshape는 차원을 계산해야 하는 로직이 추가되지만, 현대의 하드웨어에서는 무시할 만한 수준이다. 오히려 메모리 복사 여부가 성능의 관건이다.

4. 배열의 결합: concatenate, vstack, hstack

NumPy 배열은 파이썬 리스트처럼 + 연산자로 합칠 수 없다(리스트는 요소가 늘어나지만, NumPy는 요소별 덧셈이 일어난다).

  • np.concatenate((a, b), axis=0): 선택한 축을 기준으로 배열을 붙인다.
  • np.vstack (Vertical): 행(Vertical) 방향으로 쌓는다. (axis=0 연산과 유사)
  • np.hstack (Horizontal): 열(Horizontal) 방향으로 옆으로 붙인다. (axis=1 연산과 유사)

5. C 언어와의 비교: 문자열 결합

메모한 C 언어 예시는 파이썬의 편리함을 극명하게 보여준다.

  • C 언어: str1 + str2는 문자열이 저장된 메모리 주소(포인터)끼리 더하는 연산이 되어 에러가 발생하거나 엉뚱한 값을 출력한다. 따라서 <string.h> 헤더의 strcat() 함수를 사용해 메모리를 직접 할당하고 복사해야 한다.
  • Python: + 연산자 오버로딩을 통해 문자열이나 리스트를 직관적으로 합칠 수 있다. NumPy는 이 유연함을 유지하면서도, 실제 수치 연산은 C 수준의 속도로 처리하도록 설계되었다.

 

코드

vstack(수직결합), hstack(수평결합)

 

np.concatenate((a, b))와 np.vstack((a, b))는 동일한 결과를 출력

import numpy as np
# concaternate, vstack, hstack
a = np.arange(10, 18).reshape(2, 4)
print(a) # (2, 4)

b = np.arange(12).reshape(3, -1)
# b = np.arange(12).reshape(3, 4)
print(b)

c = np.arange(8).reshape(2, 4)
print(c)

d = list(range(4))
print(d)

print(np.concatenate((a, b)))

print(np.vstack((a, b)))

 

 

import numpy as np

a = np.arange(10, 18).reshape(2, 4) # (2, 4)
b = np.arange(12).reshape(3, 4)    # (3, 4)
d = np.array([1, 2, 3, 4])         # (4,) -> vstack 시 (1, 4)로 취급

print(a)
print(b)
print(d)

# 1. 수직 결합 (모두 가로가 4로 같으므로 가능)
c = np.vstack((a, b)) # 결과: (5, 4)
print(c)
print(np.vstack((a, b, d))) # 결과: (6, 4)

# 2. 수평 결합을 하고 싶다면? (세로 길이를 맞춰야 함)
# a와 똑같은 2행을 가진 배열을 만들어야 함
e = np.arange(6).reshape(2, 3) # (2, 3)
print(e)
print(np.hstack((a, e))) # 결과: (2, 7) (가로로 4+3=7)

 

np.r_과 np.c_는 함수가 아니라 '인덱서(Indexer)'이기 때문에 소괄호()가 아닌 대괄호[]를 사용

행결합: np.r_은 데이터를 행 방향(수직 또는 1차원 연장)으로 합침

열결합: 1차원 배열들을 옆으로 붙여서 열(Column)로 만들 때 사용

전치행렬: c.T: 행과 열을 바꿈. (2, 3) 행렬을 (3, 2) 행렬로 변환

# [0]*3: 3번 복사해달라는 뜻
# 삽입이 쉬워서 강력하다
a = np.array([1,2,3])
b = np.array([10, 20, 30])
c = np.array([[1,2,3],[4,5,6]])
d = np.array([[10,20,30],[40,50,60]])

# "Hello" * 3: 3번 복사하라는 뜻
print(np.r_[a, b]) # np.stack([a, b])와 같음
print(np.r_[a, 4,5,6, b])
print(np.r_[[0]*3, 5, 6])
print(np.r_[c,d])

# 1. np.r_는 대괄호 []를 사용해야 함
print(np.r_[a.reshape(-1, 1), b.reshape(-1, 1)])

# 2. np.concatenate 오타 수정
print(np.concatenate((a.reshape(-1, 1), b.reshape(-1, 1)), axis=1))
print(np.c_[a, b])
print(np.column_stack([a, b]))

# 3. np.concatenate 오타 수정
print(np.concatenate((c.T, d.T), axis=1))

 

구분 인덱서/함수 특징
수직/연장 np.r_ 대괄호 사용. 배열과 숫자를 섞어서 합치기 좋음.
수평/열 np.c_ 대괄호 사용. 1차원 배열을 열로 합칠 때 최적.
수평(함수) np.column_stack 소괄호 사용. 리스트나 튜플 형태로 입력받음.
범용 np.concatenate 반드시 차원이 일치해야 하며, axis 지정이 필요함.

 

'머신러닝' 카테고리의 다른 글

PANDAS  (0) 2026.01.08
SEABORN  (0) 2026.01.07
MATPLOTLIB  (0) 2026.01.07
넘파이(NumPy) 1  (0) 2026.01.06
파이참 설치  (0) 2026.01.05