1. numpy 란 무엇인가요?

1) 정의

numpy는 행렬, 다차원 배열을 쉽게 다룰 수 있는 파이썬 라이브러리 입니다.

2) 선형대수

선형대수 라이브러리 라고도 합니다. 선형대수는 쉽게 말하면, 행렬간 사칙연산(덧셈, 곱셈) 입니다.

2. 왜 numpy를 사용하나요?

사실, numpy를 직접적으로 사용하는 경우는 많지 않습니다.

다만, 대다수의 머신러닝 라이브러리(pandas, metplotlib 등등..)들이 numpy 기반으로 구성되어있습니다.

3. 설치

anaconda를 사용하는 경우

anaconda를 설치하는 경우 numpy도 함께 자동으로 설치됩니다.

1) numpy 설치 여부 확인

# anaconda에 설치된 python 패키지들 확인
conda list

2) 설치

설치가 완료되면 conda list를를 통해 설치 여부를 확인해줍니다.

# ananconda에 numpy설치
conda install numpy

anaconda 없이, pip 사용하는 경우

pip는 파이썬 패키지 매니저로, 파이썬 패키지들의 설치 및 버전 관리등을 지원합니다.

0) pip 버전 확인

여러개의 파이썬 버전이 설치된것이 아니라면 기본은 pip입니다. pip2, pip3는 각각 파이썬 2, 3을 설치할때 설정값에 따라 결정됩니다.

만약 설치되어있지 않다면, 다음 명령어를 수행할때 에러가 발생합니다.

# 기본값
pip --version

# python2
pip2 --version

# python3
pip3 --version

1) numpy 설치 여부 확인

사용하는 pip버전에 따른 명령어를 실행합니다.

pip list

pip2 list

pip3 list

2) 설치

pip를 이용해서 numpy를 설치합니다.

설치가 완료되면 pip list를를 통해 설치 여부를 확인해줍니다.

pip install numpy

pip2 install numpy

pip3 install numpy

4. numpy 불러오는 방법

import를 사용해서 numpy 패키지를 불러옵니다.

다만, 관례적으로 np라는 별칭을 사용합니다.

import numpy as np

# numpy를 사용해서, ndarray [1 2 3] 생성
np.array([1, 2, 3])

# numpy를 사용해서, 3.4에 버림 수행, 3.0이 됩니다.
np.floor(3.4)

5. 차원

사실, 차원이라는 단어에 큰 수학적 의미는 없습니다.

대부분 3차원에서 끝납니다. 그 이상의 경우는 생각하기 어렵습니다.

2차원을 제일 많이 사용합니다.

왜냐하면, 데이터를 효율적으로 볼 수 있는 차원이기 때문입니다. 행과 열로 이루어져 있어 머신러닝이 아니더라도 excel, database등에서 사용됩니다.

1) ndarray

numpy의 기본 데이터 타입은 ndarray입니다.
(d는 dimension 차원을 의미합니다.)

numpy는 파이썬의 리스트를 ndarray로 변환할 수 있습니다.

ndarray는 np.array() 함수를 이용해서 생성합니다.

import numpy as np

# python 리스트 생성
python_arr = [1, 2, 3]

# np.array로 npdarray 생성
numpy_arr = np.array(python_arr)

# 파이썬 기본 함수인 type으로 변수의 데이터 타입 확인
type(numpy_arr)
# 결과 <class 'numpy.ndarray'>

2) ndarray.shape

np.shape는 각 차원의 크기를 튜플로 보여줍니다.

  • np.shape는 함수가 아닌 변수(클래스의 속성)입니다. ()로 실행하지 않습니다. 클래스의 변수는 속성이라고 부름

  • 튜플은 파이썬 자료형으로 리스트와 거의 유사하며, 다른 부분은 그 요소를 바꿀 수 없다는 것입니다.

import numpy as np

# 1차원 
'''
1차원인 경우 (3) 도 아니고 (3, ) 이라고 표시됩니다. 
수학적 의미는 없고, 파이썬의 튜플이라는 자료형의 특성상 
딱 1개의 데이터를 가지는 경우 콤마를 찍고 다음을 비워둡니다.
'''
a1 = np.array([1, 2, 3])
print(a1.shape)
#결과 (3,)

# 2차원 
a2 = np.array([[1, 2, 3], [4, 5, 6]])
print(a2.shape)
#결과 (2, 3)

# 3차원 
'''
3차원인 경우 행, 열의 크기를 벗어납니다.
앞에서 부터 차례대로 첫번째 축(차원)이라고 생각하면, 각각의 차원의 크기 입니다.
'''
a3 = np.array([[[1, 2, 3], [4, 5, 6]]])
print(a3.shape)
#결과 (1, 2, 3)

3) ndarray.ndim

ndarray의 차원의 크기를 보여줍니다.

.ndim은 함수가 아닌 변수입니다.

import numpy as np

# 1차원 
a1 = np.array([1, 2, 3])
print(a1.ndim)
#결과 1

# 2차원 
a2 = np.array([[1, 2, 3], [4, 5, 6]])
print(a2.ndim)
#결과 2

# 3차원 
a3 = np.array([[[1, 2, 3], [4, 5, 6]]])
print(a3.ndim)
#결과 3

6. 데이터 타입

ndarray의 요소는 같은 데이터 타입만 가집니다.
(이를 기반으로 판다스의 series도 같은 데이터 타입만 가집니다.)

1) upcasting

동일한 데이터 타입으로 이루어진 ndarray이기 때문에 다른 데이터 타입으로 구성된 리스트로 ndarray를 생성하면 더 포괄적인 자료형으로 자료형이 변하게 됩니다.

ndarray.dtype 속성으로 데이터 타입을 확인할 수 있습니다.

import numpy as np

# 1. 정수 + 문자열 -> 문자열
num_list = [1, 2, '3']

num_array = np.array(num_list)

print(num_array.dtype)
# 결과: <U11
'''
U는 유니코드를 의미합니다. 유니코드는 가변길이 문자열 인코딩 방식입니다.
머신러닝에서는 일단 문자열을 의미함으로 알아둡십니다.
'''


# 2. 정수 + 실수 -> 실수
num_list = [1, 2, 3.4]

num_array = np.array(num_list)

print(num_array.dtype)
# 결과: float64

2) ndarray.astype()

ndarray의 데이터 타입을 변경할 수 있습니다.

생각보다 유용하게 사용됩니다.

astype() 의 인자값으로 문자열로된 데이터 형식을 넣는것이 조금 인상적입니다.

예시) astype('float64')

import numpy as np

float_list = [1.1, 2,4, 3.5]

float_array = np.array(float_list)

print(float_array.dtype)
# 결과: float64

float_array = float_array.astype('int64')

print(float_array.dtype)
# 결과: int64

7. 편하게 생성

다음 3가지 함수를 사용하면 ndarray를 만들고 초기화할 수 있습니다.

1) np.arrange()

순차적으로 증가하는 ndarray를 만듭니다.

2) np.ones()

ndarray를 만들고, 1로 초기화합니다.

3) np.zeros()

ndarray를 만들고, 0으로 초기화합니다.

import numpy as np

# 1. np.arrange()
# 범위 -1 까지 1씩 증가하는 array를 생성한다.
# 파이썬은 저렇게 끝을 포함하지 않는다.
num_array = np.arange(10)
print(num_array)

start_stop_array = np.arange(start=4, stop=9)
print(start_stop_array)


# 2. np.ones()
# ndarray를 모두 1로 초기화한다.
# 1) 차원, 2) 데이터 타입을 지정해서 생성할 수 있다.
one_array = np.ones((3, 2), dtype="int32")
print(one_array)


# 3. np.zeros()
# ndarray를 모두 0으로 초기화한다.
zero_array = np.zeros((3, ))
print(zero_array)

8. 차원 변경

1) ndarray.reshape()

reshape 함수를 사용하면 차원을 변경할 수 있습니다.

(2, 3) -> ndarray.reshape(3, 2) ->(3, 2)

2) -1을 인자로 사용

-1을 reshape인자로 사용하면 차원에 맞는 형태로 알맞게 변경해줍니다.

(2, 3) -> ndarray.reshape(3, -1) ->(3, 2)

물론, 알맞지 않은 경우(위의 경우에서는 예를 들면, 7, -1) 에는 에러가 발생합니다.

import numpy as np

# 1. (2, 3) ndarray 생성
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.shape)
# 결과 (2, 3)

# 2. (3, 2) 로 reshape
b = a.reshape(3, 2)
print(b.shape)
# 결과 (3, 2)

# 3. -1을 사용해서 (3, 2) 로 변경
c = a.reshape(3, -1)
print(c.shape)
# 결과 (3, 2)

9. 정렬

행렬을 정렬하는 방법에는 대표적으로 3가지가 있습니다.

1) np.sort() vs ndarray.sort()

np.sort()은 원래의 행렬을 인자값으로 받고, 정렬된 행렬을 반환합니다.
(단, 원래의 행렬은 변경되지 않습니다.)

ndarray.sort()는 원래의 행렬을 정렬합니다.

import numpy as np

# 1. 기본 행렬 생성
base_array = np.array([6, 4, 2, 9])
print(base_array)
# 결과: [6 4 2 9]


# 2. np.sort()
sort_array = np.sort(base_array)
print(sort_array)
# 결과: [2 4 6 9]
print(base_array)
# 결과: [6 4 2 9]


# 3. ndarray.sort()
base_array.sort()
print(base_array)
# 결과: [2 4 6 9]

2) 여러 값을 기준으로 정렬

numpy 문서를 찾아보았는데, python의 sorted와 같이 다중 조건에 오름차순, 내림차순 함께 섞는것은 없어보입니다.

만약 2차원 ndarray가 있고,
1) 행을 기준으로 내림차순, 2) 열을 기준으로 오름차순 정렬을 해야한다면

다음과 같이 axis별로 각각 수행해야할것 같습니다.

import numpy as np

# 1. 기본 행렬 생성
base_array = np.array([[1, 2, 3], [6, 5, 4]])
print(base_array)
#[[1 2 3]
# [6 5 4]]


# 2. 첫번째 축을 기준으로 정렬 - 여기서는 행
# [::-1] 을 붙여주면 역순으로 정렬한다.
first_sort = np.sort(base_array, axis=0)[::-1]
print(first_sort)
#[[6 5 4]
# [1 2 3]]


# 3. 두번째 축을 기준으로 정렬 - 여기서는 열
second_sort = np.sort(base_array, axis=1)
print(second_sort)
#[[1 2 3]
# [4 5 6]]

3) np.argsort()

np.argsort()는 원래의 행렬을 정렬하고, 그 인덱스를 반환합니다.

import numpy as np

# 1. python 리스트 생성
fruit_list = ['apple', 'banana', 'melon']
price_list = [300, 100, 500]


# 2. ndarray 생성
fruit_array = np.array(fruit_list)
price_array = np.array(price_list)


# 3. 가격 순으로 오름차순 정렬후 인덱스 반환
price_sorted_index = np.argsort(price_array)
print(price_sorted_index)
# 결과: [1 0 2]


# 4. 팬시 인덱싱 - 인덱스 집한을 기반으로 ndarray 반환
sorted_fruit_array = fruit_array[price_sorted_index]
print(sorted_fruit_array)
# 결과: ['banana' 'apple' 'melon']

10. 인덱싱

아래의 1), 2)는 파이썬에서 제공하는 기능이 ndarray에도 적용됩니다.

3), 4) 는 ndarray에만 존재합니다.

1) 단일값 추출

배열에서 인덱스를 기준으로 값에 접근하는것과 같습니다.

물론, 0부터 시작합니다.

import numpy as np

base_array = np.array([[1, 2, 3], [4, 5, 6]])
print(base_array)
"""
결과
[[1 2 3]
 [4 5 6]]
"""

print(base_array[0][2])
# 결과: 3

2) 슬라이싱

사실, python 리스트의 슬라이싱 기능이 ndarray에 그대로 적용됩니다.

파이썬에서 [1:3]이면 3이 포함되지 않는다.

import numpy as np

base_array = np.array([[1, 2, 3], [4, 5, 6]])
print(base_array)
"""
결과
[[1 2 3]
 [4 5 6]]
"""

print(base_array[:,:])
"""
결과
[[1 2 3]
 [4 5 6]]
"""
print(base_array[:1,1:3])
# 결과: [[2 3]]

3) 팬시 인덱싱

인덱스 집합을 기준으로 해당 값들을 추출하는 방법입니다.

import numpy as np

base_array = np.array([[1, 2, 3], [4, 5, 6]])
print(base_array)
"""
결과
[[1 2 3]
 [4 5 6]]
"""
 
print(base_array[[0, 1]])
"""
결과
[[1 2 3]
 [4 5 6]]
"""

print(base_array[[0, 1], [0]])
"""
결과
[1 4]
"""

4) 불린 인덱싱

조건을 기반으로 필터링 하는 방법입니다.

정말 많이 사용합니다.

주의할 부분은, and 또는 or 조건인 경우 & 또는 | 1개를 사용합니다.

파이썬에서 &가 2개면 논리 연산자, &가 1개면 비트 연산자로 동작하지만,

numpy에서는 2개면 에러가 발생하고, &가 1개일 때 논리 연산자 입니다.

import numpy as np

base_array = np.array([[1, 2, 3], [4, 5, 6]])
print(base_array)
"""
결과
[[1 2 3]
 [4 5 6]]
"""
 
print(base_array[(base_array > 1) & (base_array < 6)])
# 결과: [2 3 4 5]
# 조건의 & 또는 | 은 파이썬의 비트연산자를 의미하지 않습니다.
# 논리 연산자입니다.

참고자료

파이썬 머신러닝 완벽가이드

profile
callmeskye

1개의 댓글

comment-user-thumbnail
2020년 12월 30일

정성 가득하네요 ㅎㅎ😄

답글 달기