1. 핵심 개념
- 다차원 배열(ndarray) 기반의 고속 수치 연산 라이브러리 (자료형 numpy.ndarray 전용)
→ Python(인터프리터 언어)과 달리 연산 로직이 C로 작성된 내부 루프를 통해 직접 수행 (= 수십 배 이상 빠르게 계산)
→ for문 없이(반복제거) 배열 전체에 연산을 적용 가능한 벡터화 연산 지원 (C언어 + SIMD 명령어를 사용해서 CPU에서 병렬 계산) - 대규모 데이터 배열을 빠르게 처리하고, 과학 계산에 필수적인 기능들을 제공
→ 벡터화, 브로드캐스팅, 집계 함수 등을 통해 빠르고 효율적인 데이터 처리가 가능 - 머신러닝, 데이터 분석(통계), 고성능 과학 계산 등 다양한 분야의 기초 인프라로 사용됨
- 간단한 연산 외엔 BLAS, LAPACK, OpenBLAS, Intel MKL 등의 수학 라이브러리를 백엔드로 사용
pip install numpy # 설치 필요
import numpy as np
a = np.array([1, 2, 3, 4])
b = a * 2
※ 내장 모듈인 math, operator와 달리 표준 라이브러리에 포함되지 않기 때문에 pip 설치 필요
※ 예시의 내부 동작 정리
- a는 numpy.ndarray객체이므로 a * 2의 호출은, 사실상 a.__mul__(2)
→ Python의 일반 연산자가 아니라 C로 오버로드된 ufunc(범용 함수)라는 구조를 통해 동작 (__mul__ 오버로딩)
- ufunc는 반복 없이 배열 전체에 연산 적용, 내부는 C에서 컴파일되어 고속 실행됨
- (추가) 일부 연산은 외부 라이브러리에 맡기는데 CPU가 제공하는 SIMD 명령어(SSE, AVX 등)를 활용
※ 정렬 / 키 함수로서 사용 가능하지만 고급 연산에 더 적합함
2. 주요 함수 목록 (ufunc)
- 배열 생성
| 설명 | 예시 | |
| np.array(object[, dtype=None, copy=True, ndmin=0, order='K']) | 리스트 → ndarray 변환 | np.array([1,2,3]) |
| np.zeros(shape[, dtype=float, order='C']) | 0으로 채운 배열 생성 | np.zeros((2,3)) |
| np.ones(shape[, dtype=float, order='C']) | 1로 채운 배열 생성 | np.ones(5) |
| np.full(shape, fill_value[, dtype=None, order='C']) | 특정 값으로 채운 배열 생성 | |
| np.eye(N[, M=None, k=0, dtype=float, order='C']) | 단위 행렬 생성 | |
| np.arange([start,] stop[, step=1, dtype=None]) | range처럼 사용 (정수 또는 실수 가능) | np.arange(0, 10, 2) |
| np.linspace(start, stop[, num=50, endpoint=True, dtype=None]) | 구간을 일정 간격으로 나눈 값 생성 | np.linspace(0, 1, 5) |
| numpy.copy(a, order='K', subok=False) or ndarray.copy(order='C') |
원본과 독립된 새로운 배열 생성 (깊은 복사) | np.copy(a) or a.copy() (a는 ndarray) |
※ 매개변수 의미
- dtype : 배열의 자료형(Data Type) 지정
- copy : 원본 배열을 복사할지 여부 (True일때 복사본 생성)
- ndmin : 최소 차원 수 지정 ex) 1 → 1D, 2 → 2D
- order : 메모리 순서 지정
→ 'C' (C 언어-연속 방식) : 행 우선(row-major) (기본값), stride가 (col*itemsize, itemsize)
→ 'F' (Fortran-연 방식) : 열 우선(col-major) (행렬 계산 최적화 시 사용), stride가 (itemsize, row*itemsize)
→ 'A' : 입력 배열을 기준으로 유지 (복사 시 메모리 순서 유지)
→ 'K' : 가능한 한 원본 배열의 순서( stride )를 유지하되, 구조체 호환도 고려 (복사, 정렬, 구조체 배열을 다룰때 유용)
- N / M : 행(N), 열(M)의 개수 (M 생략시 M=N이 되는 정사각 단위행렬)
- a : array_like, 복사할 원본 배열 (리스트, 튜플 등 array_like 가능)
- subok : bool (default False)
→ True : 서브클래스 유지
→ False : 항상 ndarray로 반환
※ np.copy(a) vs a.copy()
- NumPy 모듈 vs ndarray 메서드
- 둘다 동작 방식 동일
- 실제 데이터 버퍼까지 새로 복제
→ 내부적으로 C 레벨에서 새로운 메모리 블록 할당 후 memcpy 수행
→ 따라서 깊은 복사와 동일한 효과
※ stride 란?
- 메모리에서 한 요소에서 다음 요소로 이동하는 byte 간격
- 연속된 메모리에 저장되는데, 어떤 요소를 접근할 때 몇 byte를 건너뛸지 를 나타내는 값
- stride는 배열이 메모리를 어떻게 읽는지 정의
- stride 정보만 바뀌어도 새로운 배열 처럼 보임
→ 얕은 복사는 stride만 바꿔서 새로운 모양을 만듦
→ 깊은 복사는 stride까지 새롭게 계산해서 독립된 메모리를 만듦
예시) a.T(얕은 복사, view) a.T.copy()(깊은 복사)
- 배열 정보 조회
| 설명 | 예시 | |
| a.shape | 배열의 구조 반환 | (2, 3) |
| a.ndim | 배열 차원 수 반 | 2 |
| a.size | 총 원소 개수 반환 | 6 |
| a.dtype | 배열 데이터 타입 확 | dtype('int64') |
| a.itemsize | 요소 1개의 바이트 크기 | |
| a.nbytes | 전체 메모리 크기 (byte) | |
| a.T | 전치(transpose) | |
| a.flatten([order='C']) | 다차원 배열 → 1차원으로 평탄화 | |
| a.reshape(shape[, order='C']) | 배열 모양(구조) 변경 | a.reshape(2,3) |
※ 매개변수 의미
- a : 연산 대상 배열 (입력 배열)
- 배열 연산
| 설명 | 예시 | |
| +, -, *, / | 벡터화 연산 (요소별 계산) | a + b |
| np.add(x1, x2[, out=None]) | 덧셈 | np.add(a, b) → a + b |
| np.subtract(x1, x2[, out=None]) | 뺄셈 | |
| np.multiply(x1, x2[, out=None]) | 곱셈 | np.multiply(a, b) → a * b |
| np.divide(x1, x2[, out=None]) | 나눗셈 | |
| np.power(x1, x2[, out=None]) | 제곱 | |
| np.sqrt(x[, out=None, where=True, casting='same_kind']) | 각 요소의 제곱근 반환 | np.sqrt(a) |
| np.exp(x[, out=None, where=True]) | 각 요소에 대해 자연 지수함수 e^ 반환 | np.exp(a) |
| np.sin(x[, out=None, where=True]) | 각 요소(라디안 단위)의 사인 함수 값 반환 | np.sin(a) |
| np.cos(x[, out=None, where=True]) | 각 요소(라디안 단위)의 코사인 함수 값 반환 | |
| np.dot(a, b[, out=None]) | 행렬 곱 (내적) | |
| np.sum(a[, axis=None, dtype=None, keepdims=False]) | 합계 계산 (집계 함수) | np.sum(a, axis=0) |
| np.mean(a[, axis=None, dtype=None, keepdims=False]) | 평균 계산 (집계 함수) | |
| np.std(a[, axis=None, dtype=None, ddof=0, keepdims=False]) | 표준편차 | |
| np.cumsum(a[, axis=None, dtype=None]) | 누적합 | |
| np.max(a[, axis=None, out=None, keepdims=False]) | 배열 전체 또는 지정된 축(axis)에서 최댓값 반환 | np.max(a) |
| np.min(a[, axis=None, out=None, keepdims=False]) | 배열 전체 또는 지정된 축에서 최솟값 반환 | np.min(a) |
| np.maximum(x1, x2[, out=None]) | 두 배열의 각 원소별로 큰 값 반환 | np.maximum(x, y) |
※ 매개변수 의미
- x1, x2 : 요소별 계산 대상 배열
- axis : 연산 방향 지정
→ 0 = 세로(행 단위), 1 = 가로(열 단위), None = 전체 배열에 대한 연산(축 무시)
- out : 결과 저장 배열 지정 (= 새 배열이 아닌 기존 배열에 덮어쓰기) → 메모리 재활용 목적
- where : True인 위치만 계산하고 나머지는 그대로 유지 (조건 필터링)
- casting : 자료형 변환 허용 범위 지정
→ 'no' : 자료형 변환 불가(정확히 일치), 'equiv' : 동일 표현 범위 안에서는 허용
→ 'safe' : 안전한 경우에만 허용 ex) int → float, 'same_kind' : 유사한 종류끼리 허용 ex) int ↔ float
→ 'unsafe' : 모든 형 변환 허용
- keepdims : 축(axis) 기준 연산 후, 차원 수를 유지할지 결정
→ False : 축 방향 차원이 사라짐 (기본값), True : 차원 유지 (크기가 1로 바뀜)
- ddof : 0일때 모집단 기준(기본값), 1일때 표본 기준
- 슬라이싱 & 인덱싱
| 설명 | 예시 | |
| a[start:stop[:step]] | 행/열 슬라이싱 | a[1:3], a[:, 0] |
| a[a > 3] | 조건 필터링 (Boolean Indexing) | |
| a[[1, 3, 4]] | 정수 인덱싱 | |
| a.take(indices[, axis=None]) | 인덱스 기반 추출 |
- 랜덤 생성
| 설명 | 예시 | |
| np.random.rand(d0, d1, ..., dn) | [0,1) 균일분포 난수 생성 | np.random.rand(3) |
| np.random.randn(d0, d1, ..., dn) | 표준 정규분포 | |
| np.random.randint(low[, high=None, size=None, dtype=int]) | 정수 난수 생성 | np.random.randint(1,10,5) |
| np.random.choice(a[, size=None, replace=True, p=None]) | 샘플링 | |
| np.random.shuffle(x) | 배열 섞기 (in-place) | |
| np.random.seed(seed) | 난수 고정용 시드 설정 | np.random.seed(42) |
※ 매개변수 의미
- d0, d1, ... : 배열의 각 차원 크기 지정
- 비교/논리
| 설명 | 예시 | |
| np.where(condition[, x, y]) | 조건에 따라 값 선택 | np.where(a > 0, 1, -1) |
| np.isin(element, test_elements[, assume_unique=False]) | 특정 값 포함 여부 | np.isin(a, [3, 7]) |
| np.equal(x1, x2) | 요소별 비교 (==) | |
| np.greater(x1, x2) | 요소별 비교 (>) | |
| np.logical_and(x1, x2) | 논리곱 | |
| np.all(a[, axis=None, keepdims=False]) | 모두 True인지 확인 | np.all(a > 0) |
| np.any(a[, axis=None, keepdims=False]) | 하나라도 True인지 확인 |
※ 매개변수 의미
- element : 포함 여부 확인 대상 값 (or 배열)
- test_elements : 비교 대상 배열, element가 이 안에 있는지 확인
- assume_unique : True일 경우 중복 제거 건너뜀 (성능 높임)
- 기타 함수
| 설명 | 예시 | |
| np.unique(ar[, return_index=False, return_counts=False]) | 중복 제거 후 정렬된 고유값 반환 | np.unique([1,2,1,3]) |
| np.argsort(a[, axis=-1, kind='quicksort', order=None]) | 정렬 시 인덱스 반환 | np.argsort(a) |
| np.sort(a[, axis=-1, kind='quicksort', order=None]) | 정렬 | |
| np.clip(a, a_min, a_max[, out=None]) | 값 범위 제한 | |
| np.concatenate((a1, a2, ...)[, axis=0, out=None]) | 배열 연결 | |
| np.stack(arrays[, axis=0, out=None]) | 배열 새 차원으로 쌓기 | |
| np.argmin(a[, axis=None, out=None]) | 최솟값 위치 인덱스 반환 | |
| np.argmax(a[, axis=None, out=None]) | 최댓값 위치 인덱스 반 |
※ 매개변수 의미
- kind : 정렬 알고리즘 종류
→ 'quicksort' : 빠른 정렬 (기본값), 'mergesort' : 병합 정렬 (= 순서가 유지되는 안정 정렬)
→ 'heapsort' : 힙 정렬 (= 메모리 적게 씀), 'stable' : 'mergesort'와 동일 (NumPy 1.15부터 권장)
'Language & Tool > Python' 카테고리의 다른 글
| 🐍내부에서 작동하는 이중 밑줄 메서드 (+ 네임 맹글링, 단일 밑줄) (1) | 2025.06.17 |
|---|---|
| 🐍정밀 소수점 제어 모듈, decimal (1) | 2025.06.17 |
| 🐍연산자 함수화, operator 모듈 (0) | 2025.06.16 |
| 🌱불변 텍스트 시퀸스, str(문자열) (0) | 2025.06.15 |
| 🐍try-except부터 사용자 정의 예외까지(Python) (0) | 2025.06.15 |