Numpy = Numeric Python 으로 수치 데이터를 다루기 위한 파이썬 패키지
다차원 배열 객체 ndarray
- 배열 내 같은 데이터 유형을 사용하여 메모리 효율이 높음. (리스트보다 적은 메모리를 사용)
- shape 고정 : (0d, 1d, 2d)와 같이 각 차원별 데이터의 크기(묶음 수)가 고정되어야 함. ex) [1,[2,3]]불가
- np.array([1,2,3,4])와 같이 생성
- len() 사용시 size()와 달리 첫 번째 차원의 원소 개수가 반환.
ndarray 속성
메서드가 아닌 속성을 참조하는 것이기에 () 붙이지 않고 사용.
- ndarray.ndim : 차원 수 반환
- ndarray.shape : 각 차원의 크기를 나타내는 튜플을 반환
- ndarray.size : 배열의 전체 요소 수 반환
- ndarray.dtype : 데이터 타입 반환
- ndarray.itemsize : 요소 하나의 바이트 크기를 반환
ndarray 배열 생성 함수
- np.zeros(shape) : 모든 요소가 0인 배열을 생성
- np.ones(shape) : 모든 요소가 1인 배열을 생성
- np.arange(start, stop, step) : 지정된 범위 내의 숫자로 배열을 생성
- np.linspace(start, stop, num) : 시작과 끝 사이를 균일하게 나눈 숫자로 배열을 생성, 기본적으로 끝 값 포함
- np.eye(N) : N * N 단위 행렬을 생성
인덱싱 & 슬라이싱
- Indexing : 배열의 특정 요소에 접근하는 방법
- 1차원 배열의 경우, 리스트와 동일한 방식으로 사용
- 다차원 배열에서는 콤마(,)를 사용하여 각 차원의 인덱스를 지정 → 변수[인덱스,인덱스]
ex) a[d0][d1]이 아닌 a[d0,d1]과 같이 접근. 순차 연산이 아닌 한번에 모든 축에 대해 연산을 수행. - 인덱싱 연산이 수행된 차원은 사라진다.
- Slicing : 배열의 일부분을 추출하는 방법 [start:stop:step]
- stop은 포함 X
- step은 기본값 1 사용
array_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("두 번째 행, 세 번째 열 요소:", array_2d[1,1]) # 출력: 6
print("첫 번째 열:", array_2d[:,0]) # 출력: [1 4 7]
print("중간 2x2 배열:\n", array_2d[1:3,1:3]) # 출력: [[5 6] [8 9]]
배열의 모양 변경
- reshape() : 축 별 크기 지정(shape 지정), 전체 요소 개수가 동일해야 함. 원본 데이터는 유지됨. (뷰를 반환)
- 하나의 축에는 -1값을 넣을 수 있음. (해당 축의 크기는 자동 계산)
- flatten() : 1차원 배열로 변환 후 복사본 반환
- ravel() : 1차원 배열로 변환 후 원본 배열의 뷰를 반환
배열 연산
- 기본 연산 시 같은 위치에 있는 값들끼리 계산이 수행됨. (element-wise)
내적 연산
np.dot(arr1, arr2)
arr1 @ arr2
내적 연산은 cos 유사도와 비슷하기에 내적 연산의 값을 활용. (절대값 곱의 연산은 비용이 크기에 제외)
→ 두 벡터간의 관계가 얼마나 큰지를 보여줌.
브로드캐스팅
크기가 다른 배열간의 연산도 가능하도록 도움. (비교 연산 및 논리 연산도 수행 가능)
→ 정확히 인지하고 있지 않다면 가급적 repeat이나 스칼라곱을 활용해 연산하는것을 권장
차원별 통계 계산
Numpy의 통계함수는 배열의 특정 축을 따라 계산할 수 있다.
array_2d = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(np.mean(array_2d, axis=0)) # 열별 평균 , 출력 : [4,5,6]
print(np.mean(array_2d, axis=1)) # 행별 평균 , 출력 : [2,5,8]
var(), std()를 통해 분산/표준편차를 구함에 있어 ddof(degrees of freedom, 자유도)값이 0 고정으로 설정되어 있음. → 모분산/모표준편차
분산 (Variance)
pandas의 경우 1이 기본값(분모의 n-1에서 1 부분이 ddof임)이기에 표본분산/표본표준편차를 구함.
배열 결합 및 분할
- np.concatenate() : 축을 새로 만들지 않고 기존 축에 통합
- np.vstack(), np.hstack() : 수직/수평으로 배열을 결합 (SKADA 중요)
- np.column_stack(), np.row_stack()
array_2d_1 = np.array([[1, 2], [3, 4]])
array_2d_2 = np.array([[5, 6]])
print(array_2d_1.shape)
print(array_2d_2.shape)
vstacked = np.vstack((array_2d_1, array_2d_2))
# 0번을 기준으로 통합하기에 0번축을 제외한 나머지 shape이 동일해야 함.
print(array_2d_2.T.shape)
hstacked = np.hstack((array_2d_1, array_2d_2.T))
print("수직 결합:\n", vstacked)
print("수평 결합:\n", hstacked)
.T를 통해 Transpose를 수행함으로써 hstack을 실행하기 위한 shape를 만들어줌.
Transpose시 데이터 순서가 바뀌기에 목적에 맞게 잘 사용해야 함.
- np.split() : 나눌 배열, 몇 등분할지(균등하게 나누어 떨어져야 함), 무슨 축을 기준으로 할지를 인자로 넘겨줌
- np.vsplit(), np.hsplit() : split에서 axis=0,1을 넣어준 것과 동일 효과
array_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
split_array = np.split(array_2d, 2, axis=0) # 행을 기준으로 나누기 axis=0 default
print("분할된 배열:", split_array)
split_array = np.split(array_2d, 4, axis=0)
print("분할된 배열:", split_array)
배열 파일에 저장 및 로드
- np.save() : .npy 파일 형식으로 저장
- np.savetxt() : 텍스트 파일 형식으로 저장
- np.load()
- np.loadtxt()
- np.savez() : 여러개의 배열을 하나의 파일에 .npz 형식으로 저장 (SKADA 중요)
ddof : delta degrees of freedom (자유도에서 얼마나 뺄지에 대한 값)