[Day6] Numpy/벡터/행렬

 

 

중요

Numpy performance

def sclar_vector_product(scalar, vector):
    result = []
    for value in vector:
        result.append(scalar * value)
    return result 

iternation_max = 10000000

vector = list(range(iternation_max))
scalar = 2

# for loop을 이용한 성능
%timeit sclar_vector_product(scalar, vector) 
# 1.39 s ± 61.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# list comprehension을 이용한 성능
%timeit [scalar * value for value in range(iternation_max)]
# 1.24 s ± 60.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# numpy를 이용한 성능
%timeit np.arange(iternation_max) * scalar
# 39.7 ms ± 2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

일반적으로 속도는 for loop < list comprehension < numpy 순이다.

위 실험에서는 1천만번 loop로 실험했지만 더 많은 loop에서는 차이가 더 클 것이다. Numpy는 C로 구현되어 있어, 성능을 확보하는 대신 파이썬의 가장 큰 특징인 dynamic typing이 불가하다. 대용량 계산에서 가장 흔히 사용된다. 계산이 아니라 할당에서는 연산 속도의 이점은 없다.

 

full, full_like

# np.full(shape,fill_value)
np.full(shape=(3,4),fill_value=3)
#array([[3, 3, 3, 3],
#       [3, 3, 3, 3],
#       [3, 3, 3, 3]])


# np.full_like(a,fill_value)
test_matrix=np.arange(30).reshape(5,6)
np.full_like(test_matrix,fill_value=5)
#array([[5, 5, 5, 5, 5, 5],
#       [5, 5, 5, 5, 5, 5],
#       [5, 5, 5, 5, 5, 5],
#       [5, 5, 5, 5, 5, 5],
#       [5, 5, 5, 5, 5, 5]])

full은 fill_value값을 받아 shape모양으로 새로운 배열을 만들고, full_like기존의 배열을 full함수를 사용한 배열로 바꿔준다.

 

집합 관련 함수

names=np.array(['A','B','C','A','C','B','D'])
np.unique(names)
# array(['A', 'B', 'C', 'D'], dtype='<U1')

val=np.array([6,0,0,3,2,5,3,1])
np.in1d(val,[2,3,6])
# array([ True, False, False,  True,  True, False,  True, False])

위와 같이 numpy에서는 여러 집합 관련 함수를 제공한다. 아래 여러 함수를 설명 한다.

  • unique(x): 배열 x에서 중복된 원소를 제거한 뒤 정렬하여 반환
  • intersect1d(x,y): 배열 x와 y에 공통적으로 존재하는 원소를 정렬하여 반환
  • union1d(x,y): 두 배열의 합집합을 반환
  • in1d(x,y): x의 원소가 y의 원소에 포함되는지 나타내는 불리언 배열을 반환
  • setdiff1d(x,y): x와 y의 차집합을 반환
  • setxor1d(x,y): 대칭차집합을 반환

 

repeat & tile

큰 배열을 만들기 위해 배열을 반복하거나 복제하는 함수로 repeattile이 있다.

repeat는 한 배열의 각 원소를 원하는 만큼 복제해서 큰 배열을 생성한다.

arr=np.arange(3)
arr  # array([0, 1, 2])
arr.repeat(3) #array([0, 0, 0, 1, 1, 1, 2, 2, 2])

 

만약 정수의 배열을 넘긴다면 각 원소는 배열에 담긴 정수만큼 다르게 반복될 것이다.

이때 배열과 같은 크기의 배열을 인자로 넘겨줘야 한다.

arr.repeat([2,3,4]) # array([0, 0, 1, 1, 1, 2, 2, 2, 2])

 

다차원 배열의 경우에는 특정 축을 따라 각 원소가 반복된다. repeat 메서드에 정수의 배열을 넘기면 축을 따라 배열에서 지정한 횟수만큼 원소가 반복된다.

arr=np.random.randn(2,2)
arr
#array([[ 0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733]])

arr.repeat(2,axis=0)
#array([[ 0.17517053, -0.28051293],
#       [ 0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733],
#      [ 0.60091086,  1.46553733]])

arr.repeat([2,3],axis=0)
#array([[ 0.17517053, -0.28051293],
#       [ 0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733],
#       [ 0.60091086,  1.46553733],
#       [ 0.60091086,  1.46553733]])

 

tile메서드는 축을 따라 배열을 복사해서 쌓는 함수이다. 타일을 이어붙인다고 생각하면 편하다. 위의 arr를 그냥 사용하겠다. tile메서드의 두번째 인자가 스칼라값이면 컬럼 대 컬럼이 아니라 로우대 로우로 이어 붙인다. 두번째 인자는 이어붙일 모양을 나타내는 튜플이 될 수 있다.

arr
#array([[ 0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733]])

np.tile(arr,2)
#array([[ 0.17517053, -0.28051293,  0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733,  0.60091086,  1.46553733]])


np.tile(arr,(2,1))
#array([[ 0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733],
#       [ 0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733]])

np.tile(arr,(3,2))
#array([[ 0.17517053, -0.28051293,  0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733,  0.60091086,  1.46553733],
#       [ 0.17517053, -0.28051293,  0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733,  0.60091086,  1.46553733],
#       [ 0.17517053, -0.28051293,  0.17517053, -0.28051293],
#       [ 0.60091086,  1.46553733,  0.60091086,  1.46553733]])

 

 

 

피어세션

Git

  1. 공동 수업정리 파일 만들기
  2. 과제 코드 리뷰

 

kaggle

 

피어세션 계획

  • 모더레이터 : 스티브
  • 월, 수, 금 2명씩 개인적으로 공부한 내용 발표
  • 수요일 : 무지, 네오
  • 금요일 : 라이언, 스티브
  • 럭키 : 탐, 찰스
  • 금요일마다 순서 정하기

+ Recent posts