728x90

NumPy (Numerical Python)

 

 - Array 구조의 객체 지원

 - 수학적 반복 연산을 빠르게 처리 

     * array 구조는 단 하나의 데이터 타입만 허용

     * 수학적 연산에 반복적인 벡터 연산 가능 (단, 문자 치환은 벡터 연산 불가)

 - 수학적 연산이 많은 딥러닝 수행 시 유용

     * 딥러닝 구조의 핵심 데이터 타입

 - 빠르고 효율적인 메모리 사용

 

 

# 모듈 적용

# numpy 모듈을 np로 사용                             

import numpy as np

 

 

# 생성 (.array, .arange, .random.randn)

np.array([10,20,30])

array([10, 20, 30])

 

np.arange(10)    # 0 ~ n-1 까지의 값을 갖는 1차원 배열

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

 

np.arange(5,15,2)   # n ~ m-1 까지 s 만큼의 간격의 값을 갖는 1차원 배열 

 array([ 5,  7,  9, 11, 13])

 

np.random.randn(2,3)   표준정규분포를 따르는 2차원 난수 배열 

array([[ 1.24508099,  0.29652356, -0.97754508],

       [-1.13415315,  0.73094591, -1.04153084]])

 

np.arange(10).reshape(2,5)    # 2차원 배열 

array([[0, 1, 2, 3, 4],

       [5, 6, 7, 8, 9]])

 

np.arange(24).reshape(2,3,4)   # 3차원 배열(,,), R에서는 (,,)

array([[[ 0,  1,  2,  3],

        [ 4,  5,  6,  7],

        [ 8,  9, 10, 11]],

 

       [[12, 13, 14, 15],

        [16, 17, 18, 19],

        [20, 21, 22, 23]]])

 

 

 

# 모양 변경 (.reshape)

np.arange(10).reshape(2,5)

array([[0, 1, 2, 3, 4],

         [5, 6, 7, 8, 9]])

 

 

# 2차원 배열 색인  

arr1 = np.arange(10).reshape(2,5)

array([[0, 1, 2, 3, 4],

        [5, 6, 7, 8, 9]])

 

arr1[0,2]  ==  arr1[0][2]    # 포인트 색인

2

arr1[[0,1],[1,3]]

array([1, 8])    # (0,1) (1,3) 색인

 

arr1[0]  ==  arr1[0,]  ==  arr1[0,:]     # 행 색인

 

array([0, 1, 2, 3, 4])

 

 

arr1[:,0]     # 열 색인

 

array([0, 5])

 

 

arr1[:,0:3]   # 슬라이스 색인

array([[0, 1, 2],

       [5, 6, 7]])

arr1[:2,3:]

array([[3, 4],

       [8, 9]])

 

arr1[:,[1,3]]   # 부분 색인

array([[1, 3],

       [6, 8]])

 

arr1[0,[2,3]]  ==  arr1[0][[2,3]]   

array([2, 3]))

arr1[[0,1]][:,[0,1]] 

array([[0, 1],

       [5, 6]])

 

 

 

# 3차원 배열 색인 

arr3 = np.arange(24).reshape(2,3,4)  

array([[[ 0,  1,  2,  3],

        [ 4,  5,  6,  7],

        [ 8,  9, 10, 11]],

 

       [[12, 13, 14, 15],

        [16, 17, 18, 19],

        [20, 21, 22, 23]]])

 

arr3[0]    # 층 색인 (가장 높은 차원이 우선 적용)

array([[ 0,  1,  2,  3],

       [ 4,  5,  6,  7],

       [ 8,  9, 10, 11]])

 

arr3[:,0]     # 행 색인

array([[ 0,  1,  2,  3],

       [12, 13, 14, 15]])

 

arr3[1,2,0]    # 열 색인

20

arr3[1][[0,1]][:,[0,2]]

array([[12, 14],

       [16, 18]])

 

arr3[:,0:1, 0:1]    # 슬라이스 색인 (슬라이스 사용 시 차원의 축소 방지)

array([[[ 0]],

 

       [[12]]])

 

arr3[0][[0,1],:][:,[0,1]]  ==  arr3[0:1,0:2,0:2]

array([[0, 1],      # 1층, 1,2행, 1,2열

       [4, 5]])

 

 

 

# 색인 함수 (np.ix_)

arr1 = np.arange(10).reshape(2,5)

arr1[np.ix_([0,1],[0,1])]  ==  arr1[[0,1]][:,[0,1]]  # 순차적이 아닌, 연속적 색인 가능

array([[0, 1],

       [5, 6]])

 

arr2 = np.arange(24).reshape(2,3,4) 

arr2[np.ix_([0,1],[0,2],[0,2])]  ==  arr2[[0,1]][:,[0,2]][:,:,[0,2]]  # 1,2층 / 1,3행 / 1,3열

array([[[ 0,  2],

        [ 8, 10]],

 

       [[12, 14],

        [20, 22]]])

 

 

 

# boolean 색인

arr1 = np.arange(20).reshape(4,5)

array([[ 0,  1,  2,  3,  4],

       [ 5,  6,  7,  8,  9],

       [10, 11, 12, 13, 14],

       [15, 16, 17, 18, 19]])

arr1[[True,False,True,False]]    # True 인 행 색인 (1,3행)

array([[ 0,  1,  2,  3,  4],

       [10, 11, 12, 13, 14]])

arr1[(arr1[:,3] >= 10)]     # 3번째 컬럼이 10 이상인 행 색인 

array([[10, 11, 12, 13, 14],

       [15, 16, 17, 18, 19]])

arr1[~(arr1[:,3] >= 10)]   # 위 결과의 나머지 색인 ('~' 조건의 부정)

array([[0, 1, 2, 3, 4],

       [5, 6, 7, 8, 9]])

 

 

 

# 슬라이스 색인의 뷰

a1 = np.arange(10)

a2 = a1[3:6]     # 슬라이스 색인은 원본과 동일한 메모리 영역을 사용(얇은 복사) = 뷰 객체

a2[1] = 40

a1

array([ 0,  1,  2,  3, 40,  5,  6,  7,  8,  9])

 

a1 = np.arange(10)

a2 = a1[3:6].copy()   # 원본과 메모리를 분리하기 위해 copy() 메서드 사용

a2[1] =40

a1

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

 

 

 

# 연산

# 배열 연산의 전재 조건

1) 배열 전체 크기가 동일

ar1 = np.array([10,20,30])

ar2 = np.array([100,100,100])

ar1 + ar2        (1x3, 1x3) 크기가 동일하므로 연산 가능 

array([110, 120, 130])

 

2) 같은 방향(row or column)의 크기가 동일

arr1 = np.arange(10).reshape(2,5)

arr2 = np.arange(5).reshape(1,5)

arr1 + arr2      # (2x5, 1x5) 전체 크기는 다르지만 같은 방향(column)의 크기가 동일하므로 연산 가능

                        row 수가 부족한 1x5의 배열을 반복(broadcasting) 적용

array([[ 0,  2,  4,  6,  8],

       [ 5,  7,  9, 11, 13]])

 

 

# 크기가 다른 배열을 연산하는 방법

arr1 = np.arange(10).reshape(2,5)

arr1 + arr1[:,0]     # (2x5, 1x2) 로 연산이 불가한 상황

 

1) reshape

arr1 + arr1[:,0].reshape(2,1)    # (2x5, 2x1) 로 크기를 맞추기 위해, 1x2의 배열의 모양을 변경

array([[ 0,  1,  2,  3,  4],

       [10, 11, 12, 13, 14]])

 

2) 차원의 축소 방지

arr1 + arr1[:,0:1]                # 색인 시 차원의 축소가 발생, 차원 축소 방지를 위해 슬라이스 색인을 사용

array([[ 0,  1,  2,  3,  4],

       [10, 11, 12, 13, 14]])

 

 

 

# 복사 (.array, .asarray)

l1 = [1,2,3]

arr1 = np.array(l1)     # 깊은 복사 (다른 메모리 영역 사용)

arr2 = np.asarray(l1)  # 깊은 복사 (다른 메모리 영역 사용)

arr1[0] = 10             # 리스트는 자료구조 자체가 달라지므로 모두 깊은 복사 수행 

arr2[1] = 20

l1                          # 원본 데이터는 보존

[1, 2, 3]

 

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

arr1 = np.array(arr)     # 깊은 복사 (다른 메모리 영역 사용)

arr2 = np.asarray(arr)  # 얇은 복사 (같은 메모리 영역 사용)

arr1[0] = 10

arr2[1] = 20

arr                           # asarray로 복사 후 변경한 데이터가 원본 데이터에 영향

array([ 1, 20,  3])

 

 

 

 

# Q

### 3x5 의 임시 배열을 만든 후

 

arr1 = np.zeros((3,5))

 

# 1) 첫 번째 행의 모든 데이터를 10으로 변경

 

arr1[0] = 10

 

# 2) 두 번째 행, 3,4번째 컬럼 값을 10으로 변경

 

arr1[1,[2,3]] = 10

 

# 3) (10,20,30)의 값을 갖는 배열 생성 후 위 배열과 연산(+)

 

arr2 = np.array([10,20,30])

 

arr1 + arr2.reshape(3,1)

 

###  5x4 형태의 임시 배열을 생성한 후 

arr5 = np.arange(20).reshape(5,4)

# p(1,0), p(3,1) 의 값을 출력

arr5[[1,3],[0,1]]

# 2) 위의 배열에서 arr[1:3,2:4]의 형태와 동일하게 팬시색인을 통해 출력

arr5[[1,2]][:,[2,3]]

arr5[np.ix_([1,2],[2,3])]



출처: https://data-make.tistory.com/111 [Data Makes Our Future]

+ Recent posts