Numpy란?
NumPy는 Numerical Python의 줄임말로, 과학적 계산을 위한 핵심 라이브러리입니다. 다차원 배열과 이러한 배열을 다루는 다양한 함수들을 제공하여 벡터, 행렬 등의 수치 데이터를 효율적으로 처리할 수 있습니다.
Numpy 주요 특징과 기능
- 다차원 배열(ndarray): Numpy의 핵심 데이터 구조로, N차원의 배열을 제공하며 벡터, 행렬 등을 표현할 수 있습니다.
- 배열 연산: 요소별 연산, 선형 대수, 통계 및 수학 함수 등 다양한 연산을 지원합니다.
- 브로드캐스팅: 다른 크기의 배열 간에도 연산을 가능하게 해주는 기능입니다.
- 난수 생성: 무작위 수나 난수를 생성하는 기능을 제공합니다.
- 효율적인 메모리 사용 및 벡터화된 연산: 파이썬의 루프를 사용하지 않고 벡터화된 연산을 통해 빠른 계산이 가능합니다.
API
1. 배열 생성
Numpy의 핵심 데이터 구조는 ndarray(다차원 배열)입니다. 이를 사용하여 다양한 형태의 배열을 생성할 수 있습니다.
- np.array(): 리스트나 튜플 등의 데이터로부터 배열을 생성합니다.
- np.zeros(): 모든 요소가 0인 배열을 생성합니다.
- np.ones(): 모든 요소가 1인 배열을 생성합니다.
- np.arange(): 범위를 지정하여 배열을 생성합니다.
- np.linspace(): 범위 내에서 균일한 간격으로 배열을 생성합니다.
- np.random.rand(): 무작위 수를 포함하는 배열을 생성합니다.
2. 배열 연산
Numpy는 배열 간의 다양한 연산을 지원하여 빠르고 효율적인 계산이 가능합니다.
- 요소별 연산(Element-wise operations): 배열 간의 요소별 사칙 연산(+, -, *, /)을 수행할 수 있습니다.
- 브로드캐스팅(Broadcasting): 크기가 다른 배열 간에도 연산을 가능케 하는 기능입니다.
- 통계 함수(Statistical Functions): 평균, 분산, 표준편차, 최댓값, 최솟값 등의 통계 관련 함수를 제공합니다.
3. 난수 생성
Numpy는 난수 생성을 위한 다양한 함수를 제공합니다. 이를 통해 무작위 데이터를 생성할 수 있습니다.
- np.random.rand(): 0과 1 사이의 균일 분포에서 난수 배열을 생성합니다.
- np.random.randn(): 표준 정규 분포(평균 0, 표준편차 1)에서 난수 배열을 생성합니다.
- np.random.randint(): 주어진 범위 내의 정수 난수 배열을 생성합니다.
4. 통계 함수
Numpy는 다양한 통계 함수를 제공하여 배열의 통계적 특성을 계산할 수 있습니다.
- np.mean(): 배열의 평균을 계산합니다.
- np.var(): 배열의 분산을 계산합니다.
- np.std(): 배열의 표준편차를 계산합니다.
- np.sum(): 배열의 모든 요소의 합을 계산합니다.
- np.max(), np.min(): 배열에서의 최댓값과 최솟값을 계산합니다.
코드 예시
먼저 Numpy를 사용하지 않았을때 리스트 내 합, 평균, 분산, 표준편차를 구하는 방식입니다.
# grades라는 리스트를 생성합니다.
grades = [1, 3, -2, 4]
# grades 리스트로 합, 평균, 분산, 표준편차를 구하는 함수들을 정의합니다.
def grades_sum(grades):
# 합을 구하는 함수입니다.
tot = 0
for g in grades:
tot += g
return tot
def grades_avg(grades):
# 평균을 구하는 함수입니다.
tot = grades_sum(grades)
ave = tot / len(grades)
return ave
def grades_variance(grades):
# 분산을 구하는 함수입니다.
ave = grades_avg(grades)
vari = 0
for su in grades:
vari += (su - ave) ** 2
return vari / len(grades) # 모집단으로 계산
# return vari / (len(grades) - 1) # 표본집단으로 계산 (주석 처리된 부분)
def grades_std(grades):
# 표준 편차를 구하는 함수입니다.
return grades_variance(grades) ** 0.5
# 합, 평균, 분산, 표준편차를 출력합니다.
print('합은 ', grades_sum(grades))
print('평균은 ', grades_avg(grades))
print('분산은 ', grades_variance(grades))
print('표준편차는 ', grades_std(grades))
이는 numpy 모듈을 임포트하여 사용할 시
# NumPy 모듈 임포트
import numpy as np
# NumPy를 사용하여 합, 평균, 분산, 표준편차를 출력합니다.
print('합은 ', np.sum(grades))
print('평균은 ', np.mean(grades), ' ', np.average(grades)) # mean과 average의 차이는?
print('분산은 ', np.var(grades))
print('표준편차는 ', np.std(grades))
간편하게 출력할 수 있습니다.
다음은 numpy의 ndarray를 사용하고, 주요기능중 하나인 broadcasting을 이용하여 행렬의 사칙연산을 해본 코드입니다.
# NumPy 모듈을 임포트합니다.
import numpy as np
# 리스트 ss를 생성하고, 이를 NumPy의 ndarray로 변환합니다.
ss = ['tom', 'oscar', 'john', 12, 12.3]
print(ss, type(ss))
ss2 = np.array(ss) # list를 numpy의 ndarray로 변환합니다.
print(ss2, type(ss2))
# ndarray와 리스트의 메모리 비교를 위해 리스트를 생성합니다.
li = list(range(1, 10))
print(li)
print(id(li[0]), id(li[1]))
print(li * 10)
for i in li:
print(i * 10, end=' ') # 각각의 요소값에 10을 곱합니다.
print()
# 리스트를 NumPy의 ndarray로 변환하고, ndarray의 연산을 수행합니다.
num_arr = np.array(li)
print(num_arr)
print(id(num_arr[0]), id(num_arr[1]))
print(num_arr * 10)
# NumPy 배열 생성 예시들입니다.
a = np.array([1, 2, 3]) # 1차원 배열
b = np.array([[1, 2, 3], [4, 5, 6]], dtype='float32') # 2차원 배열
c = np.zeros((2, 2)) # 모든 요소가 0인 2x2 배열 생성
d = np.ones((2, 2)) # 모든 요소가 1인 2x2 배열 생성
e = np.full((2, 2), 7) # 모든 요소가 7인 2x2 배열 생성
f = np.eye(3) # 3x3의 단위 행렬 생성
print(a, b, c, d, e, f)
# 다양한 난수 생성 방법들입니다.
rand_a = np.random.rand(2, 2) # 0~1 사이의 균일 분포를 따르는 난수 배열 생성
rand_b = np.random.randn(2, 2) # 표준 정규 분포를 따르는 난수 배열 생성
rand_c = np.random.randint(1, 10, size=(2, 2)) # 1~9 범위의 정수 난수 배열 생성
print(rand_a, rand_b, rand_c)
# 인덱싱과 슬라이싱을 통한 배열 요소 접근 예시입니다.
print(a[0]) # 배열 a의 첫 번째 요소에 접근
print(b[1, 2]) # 배열 b의 두 번째 행, 세 번째 열에 접근
print(b[:, 1:]) # 배열 b의 모든 행에서 두 번째 열 이후의 요소에 접근
# 배열 연산과 통계 함수들에 대한 예시입니다.
print(a + b) # 배열 a와 b 간의 덧셈
print(np.sum(b)) # 배열 b의 모든 요소의 합
print(np.mean(c)) # 배열 c의 평균값
# 배열을 파일로 입출력하는 예시입니다.
np.savetxt('my_array.txt', c) # 배열 c를 파일로 저장
loaded_array = np.loadtxt('my_array.txt') # 파일에서 배열 로드
# 배열의 조작(삽입, 삭제)에 대한 예시입니다.
new_arr = np.insert(a, 1, 10) # 배열 a의 두 번째 위치에 10을 삽입한 새로운 배열 생성
print(new_arr)
modified_arr = np.delete(a, 0) # 배열 a의 첫 번째 요소를 삭제한 새로운 배열 생성
print(modified_arr)
# 조건 연산과 샘플링(표본 추출)에 대한 예시입니다.
condition = (b > 3) # 배열 b에서 조건을 만족하는 요소들을 포함한 불리언 배열 생성
print(condition)
samples = np.random.choice(a, 5, replace=True) # 배열 a에서 무작위 표본을 복원 추출하여 생성
print(samples)
ndarray 란?
- NumPy의 N차원 배열 객체 입니다.
- Python의 list와 가장 큰 차이점은, 하나의 데이터 타입만 넣을 수 있다는 점입니다.
(Python List는 Dynamic typing을 지원하지만, ndarray는 지원하지 않습니다.) - 이를 위한, np.array 함수는 기존의 리스트 형태의 데이터와 데이터 타입을 입력받아 ndarray 형태로 변환해주는 함수입니다. 이때 기본 list 데이터와 원하는 데이터 타입을 지정할 수 있습니다.
파이썬은 데이터분석을 할 때 메모리를 절약하기 위해 ndarray를 사용합니다. 위 그림에서 보이듯이, python 에서 list의 경우 메모리를 많이 쓰는 반면, ndarray는 메모리 사용이 적습니다.
++ NumPy(넘파이) 라이브러리 자체가 수학적, 과학적 연산에 최적화되어있기에 선형 대수, 통계, 푸리에 변환 등 수치 계산에 필요한 다양한 기능을 제공하며,벡터화된 연산과 브로드캐스팅을 통해 반복문 없이도 배열 연산이 가능하여 빠르고 효율적인 계산이 가능하며, 또한 데이터 분석과 처리에서도 다양한 기능을 제공하여 다른 데이터 분석 도구나 라이브러리(예: Pandas, SciPy)가 NumPy를 기반으로 구축되어 있기에 NumPy와의 호환성이 높습니다.