NumPy 기초 문법

Sally·2026년 3월 20일

파이썬 Data Science

  • NumPy(넘파이) : 수치 계산의 엔진 - 행렬과 고속 계산 담당

  • Pandas : 엑셀 같은 표(Table)데이터

  • Matplotlib / Seaborn : 데이터 시각화 담당 (그래프 그리기)

  • Scikit-learn / PyTorch / TensorFlow : 머신러닝과 딥러닝 모델

    => 이 모든 라이브러리의 기반이 NumPy

import numpy as np
  • 파이썬의 리스트와 다르게 NumPy는 아래와 같은 특징을 갖는다.
    • 같은 타입만 담음 (만약 np.array([1,2,3,'4'])로 담아져있으면 자동으로 전부 문자열 취급
    • 속도 빠름 (기계어로 바로 변환 가능)
    • Vectorization : + 하면 더하기 계산을 함
import numpy as np

list_a = [1, 2, 3]
list_b = [1, 2, 3]

# 리스트 더하기: 이어 붙이기
print(list_a + list_b)
# [1, 2, 3, 1, 2, 3]

arr_a = np.array([1, 2, 3])
arr_b = np.array([1, 2, 3])

# 배열 더하기: 각 자리수끼리 계산
print(arr_a + arr_b)
# [2 4 6]

배열의 구조

NumPy 배열 (ndarray)을 생성하면 내부적으로 4가지 핵심 정보를 들고 다니는데, 이 정보를 열람하는 것이 데이터 분석의 시작이다.

import numpy as np
arr = np.array([[1, 2, 3],
                [4, 5, 6]])

print("1. 차원 수(ndim):", arr.ndim)
print("2. 모양(shape):", arr.shape)
print("3. 원소 개수(size):", arr.size)
print("4. 데이터 타입(dtype):", arr.dtype)

Shape 완전 정복

shape은 배열의 형태를 나타내는 튜플. 딥러닝에서 에러가 나면 90%는 이 shape가 안맞아서라고 한다

차원별 해석 - 오른쪽에서 왼쪽으로 읽자

  • 1차원(Vector) : (5,) -> 데이터가 5개 있는 선이 1개
  • 2차원(Matrix) : (2, 5) -> 데이터가 5개 있는 선이 2개
  • 3차원(Tensor) : (3,2,5) -> (2,5)짜리 판이, 높이로 3장 쌓임
  • 4차원(Batch) : (10, 3, 2, 5) -> (3,2,5)짜리 큐브가, 10개 있음.

축의 방향

  • sum, mean 같은 집계 함수를 쓸 때 axis는 필수 파라미터이다.
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])

# axis=0: 세로 방향 (행을 짓이김)
print("세로 합계:", arr.sum(axis=0))
# [1+4, 2+5, 3+6] -> [5, 7, 9]

# axis=1: 가로 방향 (열을 짓이김)
print("가로 합계:", arr.sum(axis=1))
# [1+2+3, 4+5+6] -> [6, 15]
  • axis = 0 : 위아래로 꾹 누름 (행이 사라짐)
  • axis = 1 : 양옆으로 꾹 누름 (열이 사라짐)

모양 바꾸기(Reshape)

import numpy as np
arr = np.arange(12) # 0부터 11까지 (12개)
print("원본:", arr)

print(arr.reshape(3, 4))   # 3행 4열로 변신
print(arr.reshape(3, -1))  # "3행으로 만들고 열은 알아서" -> (3, 4)가 됨

예제 - 0~11 배열을 (4행,3열)로 바꾸고, 가로 방향 평균 구하기

import numpy as np

# 1. 배열 생성 — 0부터 11까지 12개
arr = np.arange(12)

# 2. 모양 변경 — (4행, 3열)
arr = arr.reshape(4, 3)

# 3. 가로 방향 평균
result = arr.mean(axis=1)

print("변형된 배열:\n", arr)
print("평균값:", result)

자동 생성

  • np.zeros, np.ones, np.full
# 2x3 0 행렬 (괄호 안에 튜플로 shape를 넣으세요!)
print(np.zeros((2, 3)))

# 2x3 1 행렬
print(np.ones((2, 3)))

# 2x2 행렬을 7로 채워라
print(np.full((2, 2), 7))

구간 나누기

  • arange : 끝값 포함 X. 간격이 중요할 때
  • linspace : 끝값 포함 O. 개수가 중요할 때
# 1부터 9까지, 2씩 건너뛰며
print(np.arange(1, 10, 2))
# [1 3 5 7 9]

# 0부터 10까지, 5개 점으로 나누기 (끝값 10 포함!)
print(np.linspace(0, 10, 5))
# [ 0.   2.5  5.   7.5 10. ]

추가 문법들

난수 생성

머신러닝은 랜덤한 값(가중치)에서 시작해서 정답을 찾아가는 과정이다. 따라서 무작위 숫자를 만드는 법을 꼭 알아야 한다.

import numpy as np

# 0과 1 사이의 균일 분포 (0.xxx)
print("rand:", np.random.rand(3))

# 평균 0, 표준편차 1인 정규 분포 (가우시안)
print("randn:", np.random.randn(3))

# 범위 내의 정수 뽑기 (1부터 100까지)
print("randint:", np.random.randint(1, 101, size=5))

# 리스트에서 무작위로 뽑기
menus = ["김치찌개", "된장찌개", "돈까스", "제육볶음", "파스타"]
print("choice:", np.random.choice(menus))
  • 결과 고정하기 (Seed)
import numpy as np

# 1. 시드 고정
np.random.seed(100)

# 2. 정수 뽑기 (5개)
arr = np.random.randint(0, 10, size = 5)

# 3. 평균 출력
print("Numbers:", arr)
print("Mean:", arr.mean())

데이터 타입 변환

astype() 함수 활용

import numpy as np

arr = np.array([1.9, 2.9, 3.9])
print("원본:", arr) # [1.9 2.9 3.9] (float64)

# 정수로 변환 (소수점 버림)
int_arr = arr.astype('int')
print("변환 후:", int_arr) # [1 2 3] (int64)
  • 원본 배열을 직접 변경하지 않아서 새로운 배열에 할당해줘야함!

배열 접근 - 2차원 슬라이싱

  1. 이미지 자르기 (Cropping)
# 행: 1행부터 끝까지 (1:)
# 열: 1열부터 끝까지 (1:)
crop = matrix[1:, 1:]
  1. 특정 열만 뽑아내기
    -> 데이터 분석에서 정말 자주 쓰는 기능!
import numpy as np

matrix = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

# 0번 열(1, 4, 7)만 가져오기
col_0 = matrix[:, 0]
print("0번 열:", col_0)
  • [:,0] : 모든 행에 대해서, 0번 열만 가져와라
  • [:,1] : 두 번째 기둥

배열접근 - 불리언 인덱싱 (중요)

  • 주소가 아닌 조건(T/F)로 데이터를 찾는 것이 데이터 사이언스의 꽃이라고 할 수 있다.

  • arr[조건]

  • 조건이 True 인 칸만 살아남는다

(1) mask 있는 버전

import numpy as np

scores = np.array([80, 40, 90, 50])

# 1. 조건 만들기 (Broadcasting)
mask = scores >= 60
print(mask)
# [True, False, True, False]

# 2. 필터링 (True인 것만 가져오기)
pass_scores = scores[mask]
print(pass_scores)
# [80, 90]

(2) 한줄로 쓰기(더 많이 사용)

import numpy as np

scores = np.array([80, 40, 95, 50])

# 짝수만 골라내기
evens = scores[scores % 2 == 0]
print("짝수:", evens)

배열 접근 - Fancy Indexing

import numpy as np

arr = np.array([10, 20, 30, 40])
idx = [0, 2]

print(arr[idx]) # [10, 30]

# 팬시 인덱싱으로 수정 (원하는 위치만 골라서!)
arr[[0, 3]] = 0
print(arr)  # [  0   5   5   0]

배열 형태 변환 - 평탄화

  • 딥러닝 모델에 이미지를 넣으려면, 2차원(또는 3차원) 이미지를 한 줄(1차원)로 쭉 펴야 할 떄가 많은데, 이것을 평탄화 라고 한다.

다림질하기 (1D로 펴기)

  1. flatten(): 데이터를 복사해서 새로운 배열 만든다.(안전)
  2. ravel(): 원본 데이터를 참조함. (메모리 절약, 빠름)
  • ravel 결과를 수정하면 원본 matrix도 바뀔 수 있다.

reshape(-1)로 펴기

import numpy as np

matrix = np.array([[1, 2], [3, 4]])
print(matrix.reshape(-1))
  • ravel과 비슷하게 동작한다

배열 형태 변환 - 전치와 결합

  1. Transpose - .T 붙이기
  2. Concatenate (이어붙이기)
  • np.vstack((a,b)) : 수직으로 쌓기
  • np.hstack((a,b)) : 수평으로 쌓기

NumPy 기본 연산

  1. Element-wise Operation : 기본 연산
    +, -, *, / : 같은 위치에 있는 원소끼리 계산

  2. Matrix Multiplication : 행렬곱
    @ 또는 np.dot(a,b)

통계 연산

  1. arr.sum(), arr.mean()
  2. 축 방향
import numpy as np

arr = np.array([[1, 2], [3, 4]])

# axis=0 (위에서 아래로 꾹 누름) -> 열만 남음
print("axis=0:", arr.sum(axis=0))  # [1+3, 2+4] = [4, 6]

# axis=1 (왼쪽에서 오른쪽으로 꾹 누름) -> 행만 남음
print("axis=1:", arr.sum(axis=1))  # [1+2, 3+4] = [3, 7]
  1. 표준편차 : np.std()

위치 찾기

  • max() : 최댓값 반환
  • argmax() : 최댓값의 위치 반환
  • argmax(axis=1) : 각 행에서 가장 큰 값의 위치

선형대수와 고속 연산

브로드캐스팅 기초

  • 원래 행렬의 덧셈은 두 행렬의 모양이 완전히 같아야 가능하다.
  • (2,2) + (1,2) = 원칙적으로 불가능

하지만 NumPy에는 알아서 모양을 맞춰주는 기능이 있다. 작은 쪽을 큰 쪽에 맞춰서 쭉 늘려주는 기능인 Broadcasting이다.

import numpy as np

scores = np.array([80, 90, 70])  # (3,)
bonus = 10                        # 스칼라

# Broadcasting 발동!
# 10이 자동으로 [10, 10, 10]으로 변신해서 더해집니다.
final_scores = scores + bonus
print(final_scores)

규칙

끝에서부터 비교한다!

  • Case A : 숫자가 똑같다 (OK)
    (3,3) + (3,) -> 뒤쪽 3 일치 -> 가능

  • Case B : 둘 중 하나가 1이다.

  • (3,3) + (1,3) -> 뒤쪽 3 일치, 앞쪽 1 늘림 -> 가능

  • Case C : 숫자가 다르고 둘 다 1이 아니다 (Error)

  • (3,3) + (2,3) -> 뒤쪽 3 일치, 앞쪽 3과 2 불일치 -> 에러

브로드캐스팅 실전

  • 브로드캐스팅이 데이터 분석에서 사용되는 대표적인 예시가 데이터 정규화(Normalization)이다. 데이터 분석을 할 때, 각 데이터가 평균으로부터 얼마나 떨어져 있는지를 계산해야 할 때가 많은데, 이를 편차라고 한다.
import numpy as np

heights = np.array([170, 180, 160])  # Shape: (3,)

# 1. 평균 구하기 (Scalar)
mean_height = heights.mean()  # 170.0
print("평균 키:", mean_height)

# 2. 편차 구하기 (Broadcasting)
# (3,) - (Scalar) 연산이 일어납니다.
deviations = heights - mean_height
print("편차:", deviations)

조건부 연산

  • np.where(조건, 참일 때 값, 거짓일 때 값)

집합과 유니크

  • np.unique() : 중복 제거 + 오름차순으로 정렬된 결과를 반환
    • SQL의 DISTINCT와 동일
  • return_counts= True : 각 종류별로 몇 개 있는지 반환
import numpy as np

# 과일 바구니
basket = np.array(['apple', 'banana', 'apple', 'orange', 'banana', 'apple'])

# 종류와 개수 확인
fruits, counts = np.unique(basket, return_counts=True)

print("과일 종류:", fruits)
print("각각 개수:", counts)
# apple은 3개, banana는 2개...

선형대수1- 노름(Norm)

  • Distance를 수학적으로 정의한 것을 Norm이라고 한다.
import numpy as np

# 나의 영화 취향: [로맨스 10점, 공포 1점]
me = np.array([10, 1])

# 다른 사람의 취향: [로맨스 9점, 공포 2점]
other = np.array([9, 2])

# 차이(Difference) 벡터
diff = me - other # [1, -1]

# 거리 계산 (루트(1^2 + (-1)^2) = 루트 2 = 1.414)
dist = np.linalg.norm(diff)
print(dist)

선형대수2- 내적

@

선형대수3 - 방정식

  • 연립1차방정식 (Ax = B)
import numpy as np

A = np.array([
    [2, 1],
    [1, 1]
])
B = np.array([5000, 3000])

# X 구하기
X = np.linalg.solve(A, B)
print(X)
# [2000. 1000.] -> 사과 2000원, 바나나 1000원

선형대수4 - 역행렬

np.linalg.inv(A) : A의 역행렬 계산

  • A@inv(A) 는 단위행렬이 됨.

0개의 댓글