ThLee
ThLee의 기록장
ThLee
전체 방문자
오늘
어제
  • 분류 전체보기 (137)
    • 정보처리기사 (13)
    • 알고리즘&문제 (5)
    • 인공지능 (4)
    • 자연어처리(NLP) (6)
    • 파이썬 (24)
    • 앱인벤터 강좌 (21)
    • 리눅스 (4)
    • 프로젝트 (1)
    • (App)톡분석AI (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 정보처리기사 실기 정리
  • 블록코딩
  • Python
  • 인공지능
  • 앱인벤터 강좌
  • 정보처리기사 실기
  • 블로그
  • 딥러닝
  • 파이썬
  • 앱인벤터 블로그
  • 넘파이
  • 파이썬 넘파이
  • AI
  • 판다스
  • 앱인벤터
  • 어플
  • 정처기
  • 정보처리기사
  • 앱인벤터 무료
  • 정보처리기사 정리

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ThLee

ThLee의 기록장

[파이썬] 넘파이(Numpy) 메서드 실습
파이썬

[파이썬] 넘파이(Numpy) 메서드 실습

2022. 4. 15. 20:55
728x90

넘파이 라이브러리 불러오기

import numpy as np

numpy 라이브러리를 임포트하며, as np 는 일종의 별명입니다. 일일이 numpy라고 치는 것보다 np라고 줄여서 치는게 편하겠죠? 

(참고로 아래 예제 코드에서는 이부분을 생략할 것입니다)

리스트 선언 및 numpy array로 변환

- np.array(list) : 리스트를 numpy array로 변환

import numpy as np

# 1차원 리스트 선언
list1 = [1,2,3,4,5] 

# 2차원 리스트(행렬) 선언
list2 = [[1,2],[3,4]]

arr1 = np.array(list1) # 1차원 리스트
arr2 = np.array(list2) # 2차원 리스트

print(arr1)
>>>[1 2 3 4 5]

print(arr2)
>>>
[[1 2]
 [3 4]]

0부터 9까지 숫자를 자동으로 생성한 array 

- np.arange(값) : 값 길이의 array 생성

# 1번 방법
arr3 = np.array([0, 1,2,3,4,5,6,7,8,9])
print(arr3)
>>> [0 1 2 3 4 5 6 7 8 9]

# 2번 방법
arr3 = np.array(list(range(0,10)))
print(arr3)
>>> [0 1 2 3 4 5 6 7 8 9]

# 3번 방법
arr3 = np.arange(10)
print(arr3)
>>> [0 1 2 3 4 5 6 7 8 9]

10부터 99까지 숫자를 자동으로 생성한 array

# 위의 3번 방법 사용
arr4 = np.arange(10,100)
print(arr4)
>>>
[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]

shape을 이용한 array의 배열 형태 확인

- shape : 배열의 형태를 알려줌 

arr1 = np.array( [1,2,3,4,5] )
print(arr1)
>>> [1 2 3 4 5]
print(arr1.shape)
>>> (5,)

arr2 = np.array( [ [1,2] ,[3,4] ] )
print(arr2)
>>>
[[1 2]
 [3 4]]
print(arr2.shape)
>>> (2, 2)

arr3 = np.arange(10)
print(arr3)
>>> [0 1 2 3 4 5 6 7 8 9]
print(arr3.shape)
>>>(10,)

arr4 = np.arange(10,100)
print(arr4)
>>>
[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]
print(arr4.shape)
>>>(90,)

arr5 = np.array([[1,2], [3,4], [5,6]])
print(arr5)
>>>
[[1 2]
 [3 4]
 [5 6]]
print(arr5.shape)
>>> (3, 2)

array 배열 형태 바꾸기 

- reshape 사용

# reshape 사용
arr6 = np.arange(1,10)
print(arr6)
>>>
[1 2 3 4 5 6 7 8 9]

arr7 = np.arange(1,10).reshape(3,3)
print(arr7)
>>> 
[[1 2 3]
 [4 5 6]
 [7 8 9]]

reshape 응용 1

# row vector를 column vector로
arr8 = np.arange(6)
print(arr8)
>>> [0 1 2 3 4 5]

arr9 = np.arange(6).reshape(6,1)
print(arr9)
>>>
[[0]
 [1]
 [2]
 [3]
 [4]
 [5]]

reshape 응용 2

# 펼치기
arr9 = np.array([[1,2,3,],
             [4,5,6],
             [7,8,9]])
print(arr9)
>>>
[[1 2 3]
 [4 5 6]
 [7 8 9]]
 
print(arr9.shape)
>>> (3, 3)

print(arr9.reshape(-1,)) # -1 과 길이 값인 9와 같은 결과
>>> [1 2 3 4 5 6 7 8 9]

print(arr9.reshape(9,))  # -1 과 길이 값인 9와 같은 결과
>>> [1 2 3 4 5 6 7 8 9]

array 더하기 및 합치기

- list와 array의 차이점 중 하나는 덧셈에서 나타난다. list 2개를 더하면, 두 리스트의 요소들이 한 리스트에 모이게 되지만, array 2개를 더하면, 인덱스에 맡게 요소들을 더하게 된다.

- concatenate : 두 개의 array의 요소들을 한 array로 합치기

# list의 덧셈
[1,2,3] + [4,5,6] = [1,2,3,4,5,6]

# array의 덧셈
[1,2,3] + [4,5,6] = [5,7,9]

# array 합치기
np.concatenate( [[1,2,3], [4,5,6]] )
>>> [1,2,3,4,5,6]

array 세로로 합치기(stacking)

- vstack  사용 

# stacking vertically
arr10 = np.array([1, 2, 3])
arr11 = np.array([4, 5, 6])

print(np.concatenate([arr10,arr11]))
>>> [1 2 3 4 5 6]

print(np.vstack([arr10, arr11]))
>>>
[[1 2 3]
 [4 5 6]]

array 가로로 합치기(stacking)

- hstack 사용

# stacking vertically
arr10 = np.array([1, 2, 3])
arr11 = np.array([4, 5, 6])

print(np.concatenate([arr10,arr11]))
>>> [1 2 3 4 5 6]
print(np.hstack([arr10, arr11]))
>>> [1 2 3 4 5 6]

List와 Array의 연산 결과 비교

- array 덧셈(+), 뺄셈(-), 곱셉(*), 나눗셈(/) 등 가능

# List
list1 = [1,2,3]
list2 = [4,5,6]

print(list1 + list2)
>>> [1, 2, 3, 4, 5, 6]

# Array
arr1 = np.array([1,2,3])
arr2 = np.array([4,5,6])

print(arr1 + arr2)
>>> [5 7 9]
print(arr1 - arr2)
>>> [-3 -3 -3]
print(arr1 / arr2)
>>> [0.25 0.4  0.5 ]
print(arr1 * arr2)
>>> [ 4 10 18]

Array 내적(dot product)

- array는 내적(@)이 가능함

# dot prod 내적uct
arr1 = np.array([1,2,3])
arr2 = np.array([4,5,6])

print(arr1 @ arr2)
>> 32
# (1 x 4) + (2 x 5) + (3 x 6) = 32

브로드캐스팅과 범용 함수(Brodcast and Universal Function)

브로드캐스팅(Brodcast)란

Numpy에서 브로드캐스팅은 일정 조건을 부합하는 다른 형태의 배열끼리 연산을 수행하는 것을 의미한다.

쉽게 말하면, 서로 크기가 다른 numpy array를 연산을 수행하는 것이다.

# (1,3) array
arr1 = np.array([1,2,3])
print(arr1)
>>> [1 2 3]

# (2,3) array
arr2 = np.array([[-1,-1,-1],
                 [1,1,1]])
print(arr2)
>>> 
[[-1 -1 -1]
 [ 1  1  1]]
 
 ## 과연 두 array를 더할수 있을까요?
 # Numpy에서는 가능합니다
 
 print( arr1 + arr2 )
 >>> 
 [[0 1 2]
 [2 3 4]]
 #     arr2     +   arr1    
 # [ -1 -1 -1 ] + [ 1 2 3 ] = [ 0 1 2 ]
 # [  1  1  1 ] + [ 1 2 3 ] = [ 2 3 4 ]

범용 함수(Universal Function)란

브로드캐스팅 기능을 확장해서, numpy array의 모든 원소에 동일한 함수를 반복문으로 적용한것과 같은 효과를 내는 기능이다. sin, cos, exp, add 등 60개 이상의 범용 함수가 정의되어 있다. 

 

아래는 범용 함수 사용 안할때와 범용 함수를 사용하는 비교 해보자

결론부터 말하자면 범용 함수를 사용하면 속도가 상승한다. 아래 코드를 보면 범용 함수를 사용 안할 때는 반복문을 사용하게 되는데, 반복문을 사용하게 되면서 속도가 감소하게 된다. 범용 함수를 사용하면 반복문 없이 실행이 된다.

# 범용함수 사용 안할 때
f = lambda x : 1/x
f(3) # 0.333

arr1 = np.array([1., 2., 3.])

for i in range(arr1.shape[0]):
  arr1[i] = f(arr1[i])

print(arr1) # array([1.        , 0.5       , 0.33333333])

# 범용함수 사용할 때
arr1 = np.array([1., 2., 3.]) 
print( 1/ arr1 ) # universal fuc

넘파이 메소드(Numpy Methods) 맛보기

 

5x3 행렬 랜덤으로 만들기

# 표준정규분포에서 random sampling을 한 원소를 가지는 5x3 행렬을 만든다.
mat1 = np.random.randn(5, 3)

print(mat1)
>>>
[[-2.0687591  -0.93356275  1.18107807]
 [-1.17665873  1.72382876 -0.09030397]
 [-0.88404004  1.48126292 -0.67397981]
 [ 0.16004165  0.11851432  1.03285495]
 [-0.26317026  0.5009752   1.72397358]]

절대값

# mat1에 절대값 씌우기
print(np.abs(mat1))
>>>
[[2.0687591  0.93356275 1.18107807]
 [1.17665873 1.72382876 0.09030397]
 [0.88404004 1.48126292 0.67397981]
 [0.16004165 0.11851432 1.03285495]
 [0.26317026 0.5009752  1.72397358]]

제곱하기

# mat1 제곱하기
print(np.square(mat1))
>>>
[[4.27976422 0.87153941 1.3949454 ]
 [1.38452577 2.97158559 0.00815481]
 [0.78152679 2.19413983 0.45424878]
 [0.02561333 0.01404565 1.06678935]
 [0.06925859 0.25097615 2.9720849 ]]

제곱근 구하기

# mat1의 제곱근 구하기
print(np.sqrt(mat1))     
>>>
[[       nan        nan 1.08677416]
 [       nan 1.31294659        nan]
 [       nan 1.21707145        nan]
 [0.40005206 0.3442591  1.01629472]
 [       nan 0.70779602 1.31300174]]
 # RuntimeWarning: invalid value encountered in sqrt
 # nan = not a number : 실수값이 표현 안되는 것

범용함수 기능과 반복문의 속도 차이 실험

범용 함수 X : 루프 1번을 돌았으며, 최고 속도는 2.24 초이다

범용 함수 O : 루프 100번을 돌았으며, 최고 속도는 2.08 밀리초이다

 

결론부터 말씀드리면 범용 함수를 사용하게 되면 약 100배는 더 빠르다(100배가 맞나..? 10배인가...)

또한, 범용 함수 X는 루프 1번만 돌고, 범용 함수 O는 루프 100번을 돌았다. 이 차이가 나타나는 이유는 같은 시간을 돌았을 때, 반복문을 사용한 범용 함수X가 느리다는 것도 간접적으로 알 수 있다. 

def reverse_num(values):
    output = np.empty(len(values))
    
    for i in range(len(values)):
        output[i] = 1.0 / values[i]
    
    return output


# 1부터 100까지 범위에서 1000000개를 랜덤으로 뽑아서 array를 만듭니다.
big_array = np.random.randint(1, 100, 1000000)

print("범용함수 X : ")
%timeit reverse_num(big_array)
>>> 1 loop, best of 5: 2.24 s per loop

print("범용함수 O : ")
%timeit 1.0 / big_array
>>> 100 loops, best of 5: 2.08 ms per loop
728x90

'파이썬' 카테고리의 다른 글

[파이썬] 판다스(Pandas) 메서드 실습  (0) 2022.04.18
[파이썬] OOP 객체 지향 프로그래밍  (0) 2022.04.18
[파이썬] 판다스(Pandas) 란  (0) 2022.04.15
[파이썬] 넘파이(Numpy) 란  (0) 2022.04.15
[파이썬] 힙(Heap) 이란  (0) 2022.04.15
    '파이썬' 카테고리의 다른 글
    • [파이썬] 판다스(Pandas) 메서드 실습
    • [파이썬] OOP 객체 지향 프로그래밍
    • [파이썬] 판다스(Pandas) 란
    • [파이썬] 넘파이(Numpy) 란
    ThLee
    ThLee
    # 포트폴리오 https://thleewave.notion.site/ThLee-1fef9e057dbf40d5b7b851ab0abccf36?pvs=4 #Github - https://github.com/git-ThLee #IoT 스타트업 -Full-stack -2021.01~2021.07 -사용기술 : fluterr, arduino, node.js #코딩학원 강사 - 2019.11 ~ 진행중 - 언어 : python, 블록 코딩 - 플랫

    티스토리툴바