/ DATA-SCIENCE

Python 데이터분석 라이브러리(1) - NumPy

Data-Science 강의는 여러 절로 구성되어 있습니다.


NumPy

이번에는 NumPy(Numerical Python)에 대해서 알아보겠습니다.

NumPy module은 VectorMatrix 연산에 있어 상당한 편의성을 제공합니다. 또한 Pandas와 matplotlib의 기반이 되는 module이며 Machine Learning, Deep Learning 에서 많이 사용되기 때문에 잘 알아두어야 합니다.

NumPy array는 ndarray라고 부르는 n차원의 배열(n-dimensional array)객체입니다.

ndarray는 Python의 list와는 다르게 같은 데이터 타입만 저장 가능합니다. NumPy의 ndarray와 Python의 list는 거의 사용방법이 같지만 NumPy ndarray가 좀 더 효율적으로 메모리에 데이터를 저장하고 빠른 연산이 가능합니다.

NumPy를 사용하기 위해서는 conda 명령어나 pip를 이용하여 먼저 NumPy module을 설치해야 합니다.

conda install numpy


영상설명

이번 영상은 Anaconda를 설치하고 NumPy와 Pandas를 학습하기 위한 개발환경을 세팅하는 방법에 대한 영상입니다.

Windows 10 환경으로 진행합니다.

NumPy & Pandas - 01. Anaconda 환경설정 영상


영상설명

이번 영상은 NumPy의 ndarray 생성과 dtype 설정 및 확인에 대한 영상입니다.

ndarray 생성 및 data type 확인

다차원 ndarray와 data type 지정

NumPy & Pandas - 02. ndarray 생성 및 특징


ndarray 생성 및 type 확인



# ndarray 생성 및 type 확인

import numpy as np

a = [1,2,3,4]
print("list => {}".format(a))       # [1,2,3,4]  
print("type => {}".format(type(a))) # <class 'list'>


b = np.array([1,2,3,4])
print("array => {}".format(b))         # [1 2 3 4]
print("type => {}".format(type(b)))    # <class 'numpy.ndarray'>
print("b.dtype => {}".format(b.dtype)) # dtype : 배열 데이터 타입 속성
                                       # int32
print("b[0] type => {}".format(type(b[0]))) # <class 'numpy.int32'>


c = np.array([100,"Hello",3.141592])
print("array => {}".format(c))         # array => ['100' 'Hello' '3.141592'],  
print("type => {}".format(type(c)))    # type => <class 'numpy.ndarray'>  
print("c.dtype => {}".format(c.dtype)) # b.dtype => <U11 
print("c[0] type => {}".format(type(c[0]))) # <class 'numpy.str_'>
      

다차원 ndarray와 data type 지정

# 다차원 ndarray와 data type 지정

import numpy as np
 
my_list = [[1,2,3], [4,5,6]]
arr = np.array(my_list)

print("{}".format(arr))  # [[1 2 3]
                         #  [4 5 6]]
    
print("1행 2열의 값은 : {}".format(arr[1,2])) # 1행 2열의 값은 : 6


# ndarray 생성시 dtype 명시

# ndarray 생성 시 명시적으로 타입을 지정하지 않으면
# 데이터를 보고 적절한 타입을 알아서 지정

# 혹은 ndarray 생성 시 data type을 지정할 수 있다.

my_list = [[1,2,3], [4,5,6]]
arr = np.array(my_list, dtype=np.float64)

print("{}".format(arr))  # [[1. 2. 3.]
                         #  [4. 5. 6.]]


영상설명

이번 영상은 NumPy의 ndarray 주요 속성에 대한 영상입니다.

ndarray의 차원 관련 속성 : ndim, shape

ndarray의 크기 속성과 shape 조절

astype()을 이용한 ndarray data type 변경

NumPy & Pandas - 03.ndarray 주요속성 및 데이터타입


ndarray의 차원 관련 속성 : ndim, shape


# ndarray의 차원 관련 속성 : ndim, shape

import numpy as np

# 1차원
list = [1,2,3,4]
arr = np.array(list)

print("arr.ndim => {}".format(arr.ndim))   # arr.ndim => 1
print("arr.shape => {}".format(arr.shape)) # arr.shape => (4,)


# 2차원
list = [[1,2],[3,4],[5,6],[7,8]]
arr = np.array(list)

print("arr.ndim => {}".format(arr.ndim))   # arr.ndim => 2
print("arr.shape => {}".format(arr.shape)) # arr.shape => (4, 2)


# 3차원 (2,2,3) 형태를 list로 만들어보자!
list = [[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]
arr = np.array(list)
print("arr.ndim => {}".format(arr.ndim))   # arr.ndim => 3
print("arr.shape => {}".format(arr.shape)) # arr.shape => (2, 2, 3)


ndarray의 크기 속성과 shape 조절


# ndarray의 크기 속성과 shape 조절

import numpy as np

list = [1,2,3,4]
arr = np.array(list)

print("arr.shape => {}".format(arr.shape))   # arr.shape => (4,)
print("크기(size) : {}".format(arr.size))    # 배열 요소의 수 : 4 
print("크기(len) : {}".format(len(arr)))     # 1차원배열길이 : 4


arr.shape = 2,2    # shape 변경
print("arr.shape => {}".format(arr.shape))   # arr.shape => (2, 2)
print("크기(size) : {}".format(arr.size))    # 배열 요소의 수 : 4
print("크기(len) : {}".format(len(arr)))     # 1차원배열길이 : 2


arr.shape = 4,1,1  # shape 변경
print("arr.shape => {}".format(arr.shape))   # arr.shape => (4, 1, 1)
print(arr)


astype()을 이용한 ndarray data type 변경


 # astype()을 이용한 ndarray data type 변경

import numpy as np

arr = np.array([1.2, 2.5, 3.8, 4.2, 5.3])
print("arr.dtype : {}".format(arr.dtype))  # float64

arr = arr.astype(np.int32)
print("arr.dtype : {}".format(arr.dtype))  # int32
print(arr)  # [1 2 3 4 5]  소수점 이하 버림 처리


영상설명

이번 영상은 NumPy의 ndarray를 생성하는 다양한 생성함수에 대한 영상입니다.

ndarray 다양한 생성 함수-zeros,ones,empty,full

ndarray 다양한 생성 함수-arange

ndarray 다양한 생성 함수-linspace

NumPy & Pandas - 04.ndarray를 만드는 다양한 생성함수


ndarray 다양한 생성 함수-zeros,ones,empty,full


# ndarray 다양한 생성 함수-zeros,ones,empty,full

import numpy as np

arr = np.zeros((3,4)) # shape을 지정
                      # default data type은 float64
print(arr)

arr = np.ones((2,4), dtype=np.int32)
print(arr)

arr = np.empty((3,3)) # 공간만 할당, 초기화 하지 않는다. 
print(arr)

arr = np.full((3,4), 7, dtype=np.float64)
print(arr)   # 지정된 shape으로 array를 생성한 후
             # parameter값으로 초기화

arr = np.array([(1,2,3),(4,5,6)]) # 2 x 3 array

# 지정된 배열과 shape이 같은 array를 생성.
arr_like = np.ones_like(arr, dtype=np.float64)
arr_like = np.zeros_like(arr, dtype=np.float64)
arr_like = np.empty_like(arr, dtype=np.float64)
arr_like = np.full_like(arr, 9, dtype=np.float64)

print(arr_like)


ndarray 다양한 생성 함수-arange


# ndarray 다양한 생성 함수-arange

import numpy as np

# python의 range()와 유사
# 주어진 범위 내에서 지정한 간격으로 
# 연속적인 원소를 가진 배열을 생성
# np.arange(시작,끝,간격)
# 시작은 inclusive, 끝은 exclusive 

arr = np.arange(0,10,2)
print("arr의 크기 : {}".format(arr.size))
print("arr : ",arr)    # [0 2 4 6 8]

arr = np.arange(10)
print("arr의 크기 : {}".format(arr.size))
print("arr : ",arr)    # [0 1 2 3 4 5 6 7 8 9]

arr = np.arange(0.1,5.3)
print("arr의 크기 : {}".format(arr.size))
print("arr : ",arr)    # [0.1 1.1 2.1 3.1 4.1 5.1]


ndarray 다양한 생성 함수-linspace


# ndarray 다양한 생성 함수-linspace

import numpy as np
import matplotlib.pyplot as plt

# np.linspace(start,stop,num)
# start부터 stop의 범위에서 num개를 균일한 간격으로
# 데이터를 생성하고 배열을 만드는 함수
# 원소간 간격은 (stop-start)/(num - 1).
# num의 default값은 50

arr = np.linspace(0,10,11)
print("arr의 크기 : {}".format(arr.size))
print(arr)
plt.plot(arr,"*")   # plt.plot()은 선그래프를 그려준다.
plt.show()

arr = np.linspace(1,121,31)
print(arr)
plt.plot(arr,"o")
plt.show()


영상설명

이번 영상은 NumPy의 ndarray를 생성하는 랜덤 기반의 함수와 NumPy에서 제공하는 유용한 랜덤 관련 함수에 대한 영상입니다.

ndarray 다양한 생성 함수-random 기반

NumPy 난수관련 함수

NumPy & Pandas - 05.ndarray를 만드는 난수기반 함수


ndarray 다양한 생성 함수-random 기반


# ndarray 다양한 생성 함수-random 기반

# np.random.normal() : 정규분포 확률밀도에서 실수 표본추출
# np.random.rand() : [0,1)의 균등분포 확률밀도에서 실수 표본추출
# np.random.randn() : 표준정규분포(평균:0, 표준편차:1) 확률밀도에서 실수 표본추출
# np.random.randint() : 주어진 범위에서 균등분포 확률밀도에서 정수 표본추출
# np.random.random() : [0,1)의 균등분포 확률밀도에서 실수 표본추출

import numpy as np
import matplotlib.pyplot as plt

# np.random.normal(정규 분포의 평균,표준편차,shape)
# 정규분포 확률밀도에서 실수 표본추출
# 추출된 난수는 정규분포의 형상을 가진다.

mean = 50
std = 2
arr = np.random.normal(mean,std,(10000,))
plt.hist(arr,bins=100)
plt.show()

########################

# np.random.rand(d0,d1,d2,...)
# 난수[0,1) 균등분포 확률 밀도에서 표본을 추출
# [](대괄호)는 이상, 이하의 의미, ()(소괄호)는 초과,미만의 의미
# 추출된 난수는 균등분포의 형상을 가진다.
arr = np.random.rand(10000)
plt.hist(arr,bins=100)
plt.show()

########################

# np.random.randn(d0,d1,d2,...)
# 표준 정규 분포 확률 밀도에서 표본을 추출
# 추출된 난수는 정규분포의 형상을 가진다.
arr = np.random.randn(10000)
plt.hist(arr,bins=100)
plt.show()

########################

# np.random.randint(low,high,shape)
# 균등 분포 확률 밀도에서 정수 표본을 추출
# 추출된 정수 난수는 해당 범위에서 균등 분포의 형상을 가진다.
arr = np.random.randint(-100,100,(1000,))
plt.hist(arr,bins=100)
plt.show()

########################

# np.random.random(shape)
# [0,1) 균등 분포 확률 밀도에서 표본을 추출
# 추출된 난수는 해당 범위에서 균등 분포의 형상을 가진다.
arr = np.random.random((10000,))
plt.hist(arr,bins=100)
plt.show()


NumPy 난수관련 함수


# random 기반의 배열 생성의 재현성을 확보해보자!!
# 난수는 특정 시작 숫자로부터 난수처럼 보이는 수열을 만드는
# 알고리즘의 결과물

# 시작점을 설정하면 같은 난수를 발생시킬 수 있다. ( 난수의 재현 )
# np.random.seed(x) : 난수의 시작점을 설정하는 함수

import numpy as np

np.random.seed(1)
arr = np.random.randint(0,100,(10,))
print(arr)
# 반복실행을 해도 똑같은 난수가 발생

##################

# 데이터의 순서를 바꾸려면 shuffle()을 이용합니다. 

arr = np.arange(10)
np.random.shuffle(arr)   # arr의 데이터 순서를 변경
print(arr)

##################

# 데이터 집합에서 일부를 무작위로 선택하는 샘플링(sampling)을 
# 수행하려면 choice()를 이용합니다. 

# numpy.random.choice(a, size=None, replace=True, p=None)

# a : 배열 혹은 정수
#     만약 정수면 arange(a) 명령으로 데이터 생성
# size : 정수. 샘플 숫자
# replace : True이면 한번 선택한 데이터를 다시 선택 할 수 있음.
# p : ndarray. 각 데이터가 선택될 수 있는 확률을 명시.

arr = np.random.choice(5, 3, replace=False)
arr = np.random.choice(5, 10)
arr = np.random.choice(5, 10, p=[0.1, 0, 0.3, 0.6, 0])

print(arr)


영상설명

이번 영상은 NumPy의 ndarray shape을 변경하는 함수에 대한 영상입니다.

ndarray shape 조절 함수 - reshape

ndarray shape 조절 함수 - ravel

ndarray shape 조절 함수 - resize

NumPy & Pandas - 06.ndarray의 shape 조절 함수


ndarray shape 조절 함수 - reshape


# ndarray shape 조절 함수 - reshape

import numpy as np

arr = np.arange(0,12,1)
print(arr)

# 배열의 데이터는 공유하지만 shape이 다른 뷰(View)를 생성
arr1 = arr.reshape(4,3)
print(arr1)

# 데이터가 공유되기 때문에 배열을 변경하면 다른 View에도
# 영향을 미침
# 데이터를 공유하는지 확인

arr[4] = 100
print(arr)
print(arr1)

#######################

# base 속성을 이용하면 현재의 View의 데이터가 어떤 객체의 
# 데이터 인지를 알 수 있다.

print(arr1.base)

if arr1.base is arr:
    print("데이터 공유!!")
    
#######################

# reshape()을 사용할 때 차원 하나를 -1로 설정하면 
# 배열의 전체 원소 개수와 확정된 차원 크기로 부터 
# 남은 차원의 크기를 추론하여 배열을 생성

arr = np.arange(0,12,1)

arr1 = arr.reshape(4,-1)
print(arr1)

#######################

# View를 생성하지 않으려면 copy()를 이용하여 새로운
# array 생성

arr2 = arr.reshape(4,3).copy()


ndarray shape 조절 함수 - ravel


# ndarray shape 조절 함수 - ravel

import numpy as np

# ravel() : 배열의 모든 원소가 포함된 1차원 배열을 리턴
# ravel() 역시 View를 return

arr = np.arange(0,100,1).reshape(5,-1).copy()
print(arr)


arr1 = arr.ravel() 
print(arr1)


ndarray shape 조절 함수 - resize


# ndarray shape 조절 함수 - resize

# resize()는 reshape()과 유사한 기능을 수행.
# 단, reshape()는 배열 요소 수를 변경하지 않는반면 resize()는
# shape을 변경하는 과정에서 배열 요소 수가 변할 수 있다.

import numpy as np

np.random.seed(1)

arr = np.random.randint(0,10,(3,4))
print(arr)

# resize()를 호출하는 방식에 따라서 원본 변경 혹은
# 결과 배열이 리턴된다.
# resize()는 reshape()과는 다르게 View를 생성하지 않는다.

print(np.resize(arr,(2,6))) # 새로운 배열 생성
                            # View 생성이 아님
print(arr)

print(arr.resize(2,6)) # return 없음. 원본 변경
print(arr)

arr.resize(3,5)  # 요소수가 늘어나면 0으로 세팅
print(arr)

arr.resize(2,2)  # 요소수가 줄면 기존 데이터를 버린다.
print(arr)


영상설명

이번 영상은 NumPy의 ndarray의 indexing과 slicing에 대한 영상입니다.

ndarray indexing & slicing

ndarray Boolean indexing & Fancy indexing

NumPy & Pandas - 07.ndarray의 indexing과 slicing


ndarray indexing & slicing


# ndarray indexing & slicing

import numpy as np

arr = np.arange(10,20,1)

# ndarray는 python list처럼 indexing과 slicing이 가능

for idx,data in enumerate(arr):
    print("index : {}, data : {}".format(idx,data))
    
# ndarray를 slicing한 결과는 View이기 때문에 
# 원본 데이터가 변경되면 View의 데이터도 변경됨을 기억하자.

arr = np.arange(0,5,1)
print(arr)
print(arr[0:2])
print(arr[1:-1])
print(arr[0::2])  # 첫번째 원소부터 2씩 건너띄며 원소를 슬라이싱
print(arr[1:4:2])


# 2차원 ndarray의 indexing & slicing

arr = np.array([[1,2,3,4],
                [5,6,7,8],
                [9,10,11,12],
                [13,14,15,16]])
print(arr[1,1])
print(arr[2,:])     # 2차원 이상인 경우 
                    # ","를 기준으로 인덱싱을 해야 한다.
print(arr[1:3,:]) 
print(arr[:,2])
print(arr[1:3,:2])


ndarray Boolean indexing & Fancy indexing


# ndarray Boolean indexing & Fancy indexing

# boolean indexing은 배열의 각 요소의 선택여부를 
# True,False로 구성된 boolean mask를 이용하여 
# 지정하는 방식으로 boolean mask의 True 요소에 해당하는 
# index만을 조회.

import numpy as np

np.random.seed(1)
arr = np.random.randint(0,10,(10,))

print(arr)
print(arr % 2 == 0)       # mask 생성
print(arr[arr % 2 == 0])  # boolean indexing

##################################

# Fancy Indexing

# 배열에 index 배열을 전달하여 배열요소를 참조하는 방식

import numpy as np

arr = np.arange(0,12,1).reshape(3,4).copy()
print(arr)

print(arr[2,2])       # indexing : 10
print(arr[1:2,2])     # slicing : [6]
print(arr[1:2,1:2])   # slicing : [[5]]

print(arr[[0,2],2])   # fancy indexing : [2 10]
print(arr[[0,2],2:3]) # [[ 2]
                      #  [10]]

print(arr[:,[0,2]])   # fancy indexing  
                      # [[ 0  2]
                      #  [ 4  6]
                      #  [ 8 10]]
    
print(arr[[0,2],[0,2]]) # ?? 생각처럼 나오지 않는다.
                        # 슬라이싱처럼 fancy indexing 적용 안됨
    
# 방법 1
# 행을 먼저 추출한 후 해당 행에 대해 fancy indexing을 적용

print(arr[[0,2]][:,[0,2]])  # [[ 0  2]
                            #  [ 8 10]]

# 방법 2
# numpy의 ix_() 함수를 이용

print(arr[np.ix_([0,2],[0,2])]) # [[ 0  2]
                                # [ 8 10]]

영상설명

이번 영상은 NumPy ndarray의 사칙연산과 행렬곱연산에 대한 영상입니다.

ndarray 사칙연산과 행렬곱

ndarray broadcasting

NumPy & Pandas - 08.ndarray의 사칙연산과 행렬곱


ndarray 사칙연산과 행렬곱


# ndarray 사칙연산과 행렬곱

import numpy as np

arr1 = np.array([[1,2,3],[4,5,6]])            # 2 x 3 ndarray
arr2 = np.arange(10,16,1).reshape(2,3).copy() # 2 x 3 ndarray
arr3 = np.arange(10,16,1).reshape(3,2).copy() # 3 x 2 ndarray

# 같은 크기의 배열 간의 연산은 
# 같은 위치에 있는 원소 간의 연산으로 결과가 계산

print(arr1 + arr2)  # np.add(arr1,arr2)
print(arr1 - arr2)  # np.subtract(arr1,arr2)
print(arr1 * arr2)  # np.multiply(arr1,arr2)
print(arr1 / arr2)  # np.divide(arr1,arr2)

# 두 행렬간의 행렬곱은 np.matmul() 혹은 np.dot()으로 수행가능
# np.dot(A,B)에서 A 행렬의 열 vector와 B 행렬의 행 vector의 size가 같아야 한다.
# 그렇지 않으면 이전에 배운 reshape이나 전치행렬을 이용하여 형 변환 후 크기를
# 맞추고 연산을 수행해야 한다.

print("행렬곱 : ", np.matmul(arr1,arr3))  # np.dot(arr1,arr3)


# 이런 행렬곱을 왜 알아야 할까?
# 행렬곱이 없다면 matrix연산은 무조건 같은 크기의 사칙연산만을 수행할 수 있다.
# 하지만 행렬곱을 이용하면 
# 행렬곱 조건을 만족하는 다양한 크기의 행렬을 이용하여 연속적으로
# 행렬곱을 수행시킬 수 있기 때문.
# 이러한 특성이 Machine Learning과 Image processing에서 자주 사용된다.

# 예) 입력 : 32 x 32 matrix (image라고 가정)
#     출력 : 32 x 10 matrix (다양한 처리가 적용된 image)
#     행렬곱 : (32 x 32) dot (32 x 128) dot (128,64) dot (64 x 10) => 32 x 10

# 위의 예처럼 행렬곱 특성을 이용하면 다양한 크기의 행렬을 이용하여 원본 데이터를
# 변경시키는 것이 가능. 만약 행렬곱이 없고 사칙연산만 수행할 수 있다면
# 32 x 32 형태의 크기를 가지는 특성(행렬)만 이용할 수 있기 때문에 
# 다양한 특성을 가지는 필터 개발이 불가능하다.


ndarray broadcasting


# ndarray broadcasting

# shape이 다른 경우 두 배열에 대한 이항연산은 두 배열간의 shape을
# 맞추는 broadcasting과정을 거친 후 수행된다.
# 가장 일반적인 경우는 배열과 scalar의 연산

import numpy as np

arr1 = np.array([[1,2,3],[4,5,6]])   # 2 x 3 ndarray
arr2 = np.array([7,8,9])             # 1차원 ndarray 
print(arr1)
print(arr2)
print(arr1 + arr2)  # arr2를 2차배열로 broadcasting

arr1 = np.array([[1,2,3],[4,5,6]])
arr2 = np.array([[1,2],[4,5]])
# print(arr1 + arr2)  # broadcasting이 일어날 수 없다. Error 발생

# 주의!!
# 이런 ndarray의 broadcasting은 사칙연산에 한해서 일어나게 된다.
# 즉, 행렬곱 연산에 대해서는 broadcasting이 발생하지 않는다.


영상설명

이번 영상은 NumPy ndarray의 전치행렬과 iterator에 대한 영상입니다.

ndarray transpose

NumPy iterator

NumPy & Pandas - 09.ndarray의 전치행렬과 iterator


ndarray transpose


# ndarray transpose

# 일반적으로 전치행렬이라고 불리는 transpose에 대해서 알아보자.
# 전치행렬은 원본 행렬의 행은 열로, 열은 행으로 바꾼 행렬을 의미
# 전치행렬의 수학적 표현은 윗첨자 T를 이용해서 표현한다. 
# ndarray의 T 속성을 이용하면 전치행렬을 구할 수 있다.(View)

import numpy as np

arr = np.array([[1,2,3],[4,5,6]])   # 2 x 3 ndarray

arr_transpose = arr.T

print(arr)
print(arr_transpose)

arr[0,0] = 100

print(arr)
print(arr_transpose)   # 전치행렬 또한 View

# Vector에 대한 transpose

arr = np.array([1, 2, 3, 4])
arr_transpose = arr.T    

print(arr)
print(arr_transpose)   # vector에 대한 전치행렬은 의미없음.

# 만약 전치행렬을 구하고 싶으면 2차원 matrix로 변환한 후 수행해야 한다.

arr_transpose = arr.reshape(1,4).T
print(arr_transpose)


NumPy iterator


# ndarray iterator

# ndarray의 모든 원소를 access하는 경우에 일반적으로 iterator를 이용.
# iternext()와 finished 속성을 이용하여 ndarray의 모든 요소들을 순차적으로
# access 할 수 있다.

import numpy as np

# 1차원 ndarray에 대한 요소 출력
arr = np.array([1, 2, 3, 4, 5])

for tmp in arr:
    print(tmp, end=' ')
    
####################################    

# 1차원 ndarray에 대한 iterator

arr = np.array([1, 2, 3, 4, 5])

it = np.nditer(arr, flags=['c_index'])

while not it.finished:
    
    idx = it.index
    
    print(arr[idx], end=' ')
    
    it.iternext()

####################################

# 2차원 ndarray에 대한 요소 출력
arr = np.array([[1,2,3], [4,5,6]])

for tmp1 in range(arr.shape[0]):
    for tmp2 in range(arr.shape[1]):
        print(arr[tmp1,tmp2], end=' ')
        
####################################    

# 2차원 ndarray에 대한 iterator

arr = np.array([[1,2,3], [4,5,6]])

it = np.nditer(arr, flags=['multi_index'])

while not it.finished:
    
    idx = it.multi_index
    
    print(arr[idx], end=' ')
    
    it.iternext()        


영상설명

이번 영상은 NumPy ndarray의 boolean mask의 활용과 집계함수에 대한 영상입니다.

ndarray 비교연산

NumPy 함수와 axis

NumPy 집계 함수의 처리속도

Boolean Mask 활용

NumPy & Pandas - 10.ndarray의 boolean mask와 집계함수


ndarray 비교연산


# ndarray 비교연산

# 사칙연산과 마찬가지로 비교연산도 같은 index의 
# 요소들끼리 수행된다.

import numpy as np

arr1 = np.random.randint(0,10,(2,3))
arr2 = np.random.randint(0,10,(2,3))

print(arr1)
print(arr2)


print(arr1 == arr2) # 논리 연산의 결과는 boolean
print(arr1 > arr2)

#######################

# 2개의 ndarray 자체가 같은 데이터를 가지고 있는지
# 비교할 때는 array_equal()을 사용한다.

arr1 = np.arange(10)
arr2 = np.arange(10)

print(np.array_equal(arr1,arr2)) # 두 배열 전체 비교


NumPy 함수와 axis


# NumPy 함수와 axis

import numpy as np
import matplotlib.pyplot as plt

arr = np.arange(1,7,1).reshape(2,3).copy()
print(arr)

print(np.sum(arr))        # 합, arr.sum()
print(np.cumsum(arr))     # 누적합, arr.cumsum()
print(np.mean(arr))       # 평균, arr.mean()
print(np.max(arr))        # 최대값, arr.max() 
print(np.min(arr))        # 최소값, arr.min()
print(np.argmax(arr))     # 최대값의 index => 5
print(np.argmin(arr))     # 최소값의 index => 0
print(np.std(arr))        # 표준편차, arr.std() 
print(np.sqrt(arr))       # 제곱근
print(np.exp(arr))        # 자연상수의 제곱값 (자연상수 e = 2.7182...)
print(np.log10(arr))      # 상용 log의 값
print(np.log(arr))        # 자연 log의 값 (자연상수 e = 2.7182...)

print(np.log10(100))      # 상용로그 
print(np.log(2.7182))     # 자연로그 

arr = np.arange(1,10000,1)
arr1 = np.log10(arr)
print(arr1)

plt.plot(arr1)
plt.show()


# NumPy의 모든 집계함수는 axis를 기준으로 계산.
# 만약 axis를 지정하지 않으면 axis는 None으로 간주하고
# 대상범위를 전체 행렬로 지정

import numpy as np

arr1 = np.array([1,2,3,4,5])
print(arr1.sum(axis=0)) # 1차원에서 axis=0은 열방향
#print(arr1.sum(axis=1)) # 1차원에서 axis=1은 error

arr1 = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(arr1)
print(arr1.sum()) # axis=None, 전체배열대상 => 45
print(arr1.sum(axis=0)) # 2차원에서 axis=0은 행방향, np.sum(arr1,axis=0)
print(arr1.sum(axis=1)) # 2차원에서 axis=1은 열방향, np.sum(arr1,axis=1)
print(arr1.argmax(axis=1)) # 열방향으로 최대값의 index => [2 2 2]

arr1 = np.random.randint(0,5,(2,2,3))
print(arr1)
print(arr1.sum(axis=0)) # 3차원에서 axis=0은 depth방향


NumPy 집계 함수의 처리속도


# NumPy 집계 함수의 처리속도

import numpy as np

arr = np.arange(10000000, dtype=np.float64)

# 아래의 코드는 jupyter notebook의 cell을 나누어서 실행

%%time
# 해당 cell을 실행시키는데 걸리는 시간 출력출력

result = 0.0
for tmp in arr:
    result += tmp
print(result)    

##########################

%%time
print(arr.sum())


Boolean Mask 활용


# Boolean Mask 활용

import numpy as np

arr = np.array([[1,2,3,4],
                [5,6,7,8],
                [9,10,11,12],
                [13,14,15,16]])

# ndarray arr안에 10보다 큰 수가 몇개있는지 알아보려면
# 어떻게 해야 하는가?
# 여러가지 방법이 있지만 가장 쉽고 빠른 방법은 
# boolean indexing을 이용하는 방법

# arr > 10 => boolean mask
# True는 1로, False는 0으로 간주된다는 것을 기억하자.

(arr > 10).sum()    # 조건을 만족하는 개수(True의 개수)


영상설명

이번 영상은 NumPy ndarray의 정렬, 연결, 삭제에 대한 영상입니다.

ndarray 정렬

NumPy concatenate() 함수

ndarray delete() 함수

ndarray loadtxt() 함수

NumPy & Pandas - 11.ndarray의 정렬, 연결, 삭제


ndarray 정렬


# ndarray 정렬

# NumPy의 array는 axis를 기준으로 정렬하는 sort() 제공
# 만약 axis를 지정하지 않으면 -1, 
# -1의 의미는 마지막 axis
# np.sort() : 정렬된 결과 배열을 return
# arr.sort() : 원본배열을 정렬. None return

import numpy as np

arr = np.arange(10)
np.random.shuffle(arr)      # shuffle 처리
print(arr)

print(np.sort(arr))         # 오름차순 정렬한 새로운 배열 return
print(np.sort(arr)[::-1])   # 내림차순 정렬, 특수한 indexing이용
print(arr)                  # 원본은 변함없음

arr = np.random.randint(0,10,(3,3))
print(arr)
print(np.sort(arr, axis=0))

#################################

# 2차원 배열 정렬
import numpy as np

arr = np.array([[10,2,12,4],
                [15,16,3,8],
                [9,1,11,7],
                [13,14,5,6]])

print(arr)
print(np.sort(arr,axis=0))    # 행 방향 정렬
print(np.sort(arr,axis=1))    # 열 방향 정렬

# 표준정규분포에서 
# 200개의 샘플을 추출한 후 
# 내림차순으로 상위 5%까지의 결과만 출력하세요!!

arr = np.random.randn(200)
result = np.sort(arr)[::-1][:int(0.05 * len(arr))]
print(result)


NumPy concatenate() 함수


# NumPy concatenate() 함수

# ndarray에 row(s) 또는 column(s)을 추가하기 위한 함수

import numpy as np

arr = np.array([[1,2,3], [4,5,6]])

new_row = np.array([7,8,9])

result = np.concatenate((arr,new_row.reshape(1,3)), axis=0)

print(result)

######################################

arr = np.array([[1,2,3], [4,5,6]])

new_col = np.array([7,8,9,10])

result = np.concatenate((arr,new_col.reshape(2,2)), axis=1)

print(result)



ndarray delete() 함수


# ndarray delete() 함수

# delete() 함수는 axis를 기준으로 행과 열을 삭제
# axis를 지정하지 않으면 1차배열로 변환 후 삭제
# 원본배열을 변경하지 않고 새로운 배열 return

import numpy as np

arr = np.random.randint(0,10,(3,4))
print(arr)

#####################

result = np.delete(arr,1)  # 1차 배열로 변환 후 1번 index 삭제
print(result)

#####################

result = np.delete(arr,1, axis=0)  # 1번 행 삭제
print(result)

#####################

result = np.delete(arr,3, axis=1)  # 3번 행 삭제
print(result)


ndarray loadtxt() 함수


# ndarray loadtxt() 함수

# numpy.loadtxt(fname, dtype='float', delimiter=' ', 
#  			    skiprows=0, usecols=None, unpack=False, ndmin=0, 
#               encoding='bytes', max_rows=None>
# 형식으로 사용됩니다. CSV 파일등으로부터 데이터를 읽어 ndarray를 생성하기 위한
# 함수라고 보시면 됩니다.

import numpy as np

arr = np.loadtxt("./data/seoul.csv", delimiter=",", dtype=np.object,
                 skiprows=1)

print(arr)

End.


Data-Science 강좌는 아래의 책과 사이트를 참조했습니다. 조금 더 자세한 사항을 알고 싶으시면 해당 사이트를 방문하세요!!