왜 Numpy를 배워야 할까? -1 (배열 생성, 차원 변환, ...)
1. Numpy 소개
* Numpy 란?
넘파이(Numpy, Numerical Python)는 파이썬에서 과학적 계산을 위한 핵심 라이브러리 중 하나이다.
단순한 문법과 폭넓은 호환성으로 널리 사용되고 있는 파이썬이지만, 대규모 수치 연산을 할 때 느려진다는 치명적인 단점이 있다. 이를 보완하기 위해 만들어진 파이썬 라이브러리가 바로 넘파이이다. C언어로 구현되어 있는 넘파이는 연산 속도가 빠르며, 다양한 함수와 배열 연산 기능을 제공한다.
* Numpy 장점
1. 효율적인 수치 계산
- 고성능 다차원 배열 객체(ndarray): 넘파이의 핵심은 다차원 배열 객체이다. 이는 대규모 데이터 집합을 효율적으로 저장하고 조작하는 데 사용된다.
- 수학적 함수 라이브러리: 넘파이는 다양한 수학적 함수들을 제공하여 배열 간의 빠르고 효율적인 연산을 가능하게 한다.
2. 데이터 과학의 기초
- 데이터 변환 및 조작: 넘파이는 배열의 형태 변경, 슬라이싱, 인덱싱, 브로드캐스팅 등 데이터 조작에 관한 다양한 기능을 지원한다. 이러한 기능은 데이터 분석 작업에서 필수적이다.
- 넘파이는 데이터 사이언스와 머신러닝 분야에서 널리 사용되는 기초적인 라이브러리이다.
3. 다양한 라이브러리와의 호환성
- 넘파이는 Pandas, Matplotlib, Scipy와 같은 다른 데이터 과학 라이브러리와 잘 호환된다. 이를 통해 더 복잡한 데이터 작업을 수행할 수 있다.
2. ndarray 개요
* numpy 모듈 임포트
import numpy as np
- as np를 생략해도 괜찮지만 약어인 np를 사용하는 것이 관례적이다.
* ndarray 배열 생성하기
- 넘파이의 기반 데이터 타입은 ndarray이다.
- 넘파이 array( ) 함수는 파이썬의 리스트와 같은 다양한 인자를 입력받아서 ndarray로 변환하는 기능을 수행한다.
array_1 = np.array([1, 2, 3, 4, 5])
print(array_1)
print('array_1d array type : ', type(array_1))
print('array_1d 형태 : ', array_1.shape)
array_2 = np.array([[1, 2, 3], [4, 5, 6]])
print(array_2)
print('array_1d array type : ', type(array_2))
print('array_1d 형태 : ', array_2.shape)
array_3 = np.array([[1, 2, 3]])
print(array_3)
print('array_1d array type : ', type(array_3))
print('array_1d 형태 : ', array_3.shape)
[output]
# array_1
[1 2 3 4 5]
array_1 array type : <class 'numpy.ndarray'>
array_1 형태 : (5,)
# array_2
[[1 2 3]
[4 5 6]]
array_2 array type : <class 'numpy.ndarray'>
array_2 형태 : (2, 3)
# array_3
[[1 2 3]]
array_3 array type : <class 'numpy.ndarray'>
array_3 형태 : (1, 3)
- ndarray.shape는 ndarray 차원과 크기를 튜플 형태로 나타내 준다.
- array_1의 (5,)는 1차원 array로 5개의 데이터를 가지고 있음을 뜻한다.
- array_2의 (2, 3)은 2차원 array로, 2개의 row와 3개의 column으로 구성되어 있음을 뜻한다.
- array_3의 (1, 3)도 2차원 array로, 1개의 row와 3개의 column으로 구성되어 2*3=6개의 데이터를 가지고 있음을 뜻한다.
* ndarray 차원 확인하기
- 각 array의 차원을 ndarray.ndim을 이용해 확인 가능하다.
print('array_1 :{0}차원, array_2 :{1}차원, array_3 :{2}차원'.format(array_1.ndim, array_2.ndim, array_3.ndim))
[output]
array_1 : 1차원, array_2: 2차원, array_3 : 2차원
- array_1의 리스트 [ ]는 1차원이고, array_2의 리스트의 리스트[[ ]]는 2차원과 같은 형태이다.
3. ndarray의 데이터 타입
- ndarray내의 데이터값은 숫자 값, 문자열 값, 불 값 등이 모두 가능하다.
- ndarray내의 데이터 타입은 그 연산의 특성상 같은 데이터 타입만 가능하다.
* ndarray 데이터 타입 확인하기
- ndarray내의 데이터 타입은 dtype 속성으로 확인 가능하다.
list1 = [1, 2, 3]
print(type(list1))
array1 = np.array(list1)
print(type(array1))
print(array1, array1.dtype)
[output]
<class 'list'>
<class 'numpy.ndarray'>
[1 2 3] int64
- 리스트 자료형인 list1은 integer 숫자인 1, 2, 3을 값으로 가지고 있으며, 이를 ndarray로 쉽게 변경 가능하다.
- 이렇게 변경된 ndarray 내의 데이터값은 모두 int32형이다.
* 데이터값의 타입이 다른 리스트를 ndarray로 변환하기
list2 = [1, 2, 'test']
array2 = np.array(list2)
print(array2, array2.dtype)
list3 = [1, 2, 3.0]
array3 = np.array(list3)
print(array3, array3.dtype)
[output]
['1' '2' 'test'] <U21
[1. 2. 3.] float64
- int형 값과 문자열이 섞여있는 list2를 ndarray로 변환한 array2는 int형 값 1, 2가 모두 문자열 값인 '1', '2'로 변환되었다.
- int형과 float형이 섞여있는 list3의 경우도 숫자형 값 1, 2가 모두 1. 2. 인 float형으로 변환되었다.
- ndarray는 데이터값이 모두 같은 데이터 타입이어야 하므로 서로 다른 데이터 타입이 섞여 있을 경우 데이터 타입이 더 큰 데이터 타입으로 변환된다.
* ndarray 데이터값 타입 변경하기
- ndarray 내 데이터값의 타입 변경도 astype() 메서드를 이용 가능하다.
array_int = np.array([1, 2, 3])
array_float = array_int.astype('float64')
print(array_float, array_float.dtype)
array_int1 = array_float.astype('int32')
print(array_int1, array_int1.dtype)
array_float1 = np.array([1.1, 2.2, 3.3])
array_int2 = array_float1.astype('int32')
print(array_int2, array_int2.dtype)
[output]
[1. 2. 3.] float64
[1 2 3] int32
[1 2 3] int32
- astype( )에 인자로 원하는 타입을 문자열로 지정하면 된다.
- float를 int형으로 변경할 경우 소수점 이하는 모두 없어진다.
4. ndarray를 편리하게 생성하기
- 특정 크기와 차원을 가진 ndarray를 연속값이나 0또는 1로 초기화해 쉽게 생성해야 할 필요가 있는 경우가 발생할 수 있다.
* arange ( )
- array를 range( )로 표현하는 것이다.
- 0부터 함수 인자 값 -1까지의 순차적으로 ndarray의 데이터값으로 변환해 준다.
sequence_array = np.arange(10)
print(sequence_array)
print(sequence_array.dtype, sequence_array.shape)
[output]
[0 1 2 3 4 5 6 7 8 9]
int64 (10,)
- default 함수 인자는 stop 값이며, 0부터 9까지의 숫자 값으로 구성된 1차원 ndarray를 만들어준다.
- 시작값도 설정 가능하다. ex) np.arrange(5, 11) : 5부터 10까지
* zeros( ), ones( )
- zeros( )는 함수 인자로 튜플 형태의 shape 값을 입력하면 모든 값을 0으로 채운 해당 shape를 가진 ndarray를 반환한다.
- ones( )는 함수 인자로 튜플 형태의 shape 값을 입력하면 모든 값을 1로 채운 해당 shape를 가진 ndarray를 반환한다.
zero_array = np.zeros((3, 2), dtype = 'int32')
print(zero_array)
print(zero_array.dtype, zero_array.shape)
one_array = np.ones((3, 2))
print(one_array)
print(one_array.dtype, one_array.shape)
[output]
[[0 0]
[0 0]
[0 0]]
int32 (3, 2)
[[1. 1.]
[1. 1.]
[1. 1.]]
float64 (3, 2)
- 함수 인자로 dtype을 정해주지 않으면 default로 float64 형의 데이터로 ndarray를 채운다.
5. ndarray의 차원과 크기를 변경하는 reshape( )
* reshape( ) 사용하기
- reshape( ) 메서드는 ndarray를 특정 차원 및 크기로 변환한다.
array1 = np.arange(10)
print('array1:\n', array1)
array2 = array1.reshape(2, 5)
print('array2:\n', array2)
array3 = array1.reshape(5, 2)
print('array3:\n', array3)
[output]
array1:
[0 1 2 3 4 5 6 7 8 9]
array2:
[[0 1 2 3 4]
[5 6 7 8 9]]
array3:
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
- 지정된 사이즈로 변경이 불가능하면 오류 발생
* 인자로 -1 사용하기
- 실전에서 더욱 효율적으로 사용하려면 -1을 인자로 사용하면 된다. -1을 사용하면 원래 ndarray와 호환되는 새로운 shape로 변환해 준다.
array1 = np.arange(10)
print(array1)
array2 = array1.reshape(-1, 5)
print('array2 shape : ', array2.shape)
array3 = array1.reshape(5, -1)
print('array3 shape : ', array3.shape)
[output]
[0 1 2 3 4 5 6 7 8 9]
array2 shape : (2, 5)
array3 shape : (5, 2)
- (-1, 5)는 고정된 5개의 컬럼에 맞는 로우를 자동으로 새롭게 생성해 변환하라는 의미이다.
- 물론 -1을 사용하더라도 호환될 수 없는 형태는 변환할 수 없다. ex) (-1, 4), (3, -1),...
* -1 인자 활용하기
array1 = np.arange(8)
array3d = array1.reshape((2, 2, 2))
print('array3d : \n', array3d.tolist())
# 3차원 ndarray를 2차원 ndarray로 변환
array5 = array3d.reshape(-1, 1)
print('array5 : \n', array5.tolist())
print('array5 shape : ', array5.shape)
# 1차원 ndarray를 2차원 ndarray로 변환
array6 = array1.reshape(-1, 1)
print('array6 : \n', array6.tolist())
print('array6 shape : ', array6.shape)
[output]
array3d :
[[[0, 1], [2, 3]], [[4, 5], [6, 7]]]
array5 :
[[0], [1], [2], [3], [4], [5], [6], [7]]
array5 shape : (8, 1)
array6 :
[[0], [1], [2], [3], [4], [5], [6], [7]]
array6 shape : (8, 1)
* 참고 도서
- 저자
- 권철민
- 출판
- 위키북스
- 출판일
- 2022.04.21