ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [NumPy_4] 기존 데이터에서 배열 만들기 / 배열 연산
    NAN/Python 2021. 6. 30. 22:37
    728x90

     

    배열 쌓기, 배열 쪼개기

     


    기본 형태

     

    np.vstack(tuple) : 두 배열을 세로로 쌓아 하나의 배열을 만든다. 

    np.hstack(tuple) : 두 배열을 가로로 쌓아 하나의 배열을 만든다. 

     

    • np.vstack(arr1, arr2)의 형태로 array가 튜플 타입으로 들어간다.
    • 첫 번째 축을 제외하고 모두 같은 모양이어야 하고, 1차원 배열은 길이가 같아야 한다.

     

    arr1 = np.array([[1, 1],[2, 2]])
    arr2 = np.array([[3, 3],[4, 4]])
    
    arr_vstack = np.vstack((arr1, arr2))
    print(arr_vstack)
    
    [[1 1]
     [2 2]
     [3 3]
     [4 4]]
    
    arr_hstack = np.hstack((arr1, arr2))
    print(arr_hstack)
    
    print(arr_hstack)
    [[1 1 3 3]
     [2 2 4 4]]

     

    기본 형태

     

    np.vsplit(arr, indices_or_sections) : 하나의 배열을 세로로 쪼개 n개의 배열을 만든다.

    np.hsplit(arr, indices_or_sections) : 하나의 배열을 가로로 쪼개 n개의 배열을 만든다.

     

    • arr1, arr2, arr3 = np.vsplit(array,3)의 형태로 사용한다.
    • v, h에 따라 행, 열 방향을 기준
    • indices_or_sections : int 또는 나누고 싶은 행을 입력하여 사용한다.

     

    행방 향 나누기

    arr = np.arange(1,25).reshape(6, 4)
    print(arr)
    
    [[ 1  2  3  4]
     [ 5  6  7  8]
     [ 9 10 11 12]
     [13 14 15 16]
     [17 18 19 20]
     [21 22 23 24]]
     
    arr1,arr2,arr3 = np.vsplit(arr, 3)
    print(arr1)
    print()
    print(arr2)
    print()
    print(arr3)
    
    [[1 2 3 4]
     [5 6 7 8]]
    
    [[ 9 10 11 12]
     [13 14 15 16]]
    
    [[17 18 19 20]
     [21 22 23 24]]
    # 나누고싶은 행을 선택한 경우
    
    arr_row1, arr_row2, arr_row3 = np.vsplit(arr,(3,5))
    print(arr_row1)
    print()
    print(arr_row2)
    print()
    print(arr_row3)
    
    [[ 1  2  3  4]
     [ 5  6  7  8]
     [ 9 10 11 12]]
    
    [[13 14 15 16]
     [17 18 19 20]]
    
    [[21 22 23 24]]

     

    열 방향 나누기

     

    arr = np.arange(1,25).reshape(2,12)
    print(arr)
    
    [[ 1  2  3  4  5  6  7  8  9 10 11 12]
     [13 14 15 16 17 18 19 20 21 22 23 24]]
     
    arr1,arr2,arr3 = np.hsplit(arr, 3)
    print(arr1)
    print()
    print(arr2)
    print()
    print(arr3)
    
    [[ 1  2  3  4]
     [13 14 15 16]]
    
    [[ 5  6  7  8]
     [17 18 19 20]]
    
    [[ 9 10 11 12]
     [21 22 23 24]]

     

    vsplit()와 마찬가지로 나누고 싶은 열을 지정하여 나눌 수 있다.

     

     


     

    깊은 복사, 얕은 복사

     

     

    예를 들어 arr1 = ([1,2,3,4])라는 데이터를 가지고 있다고 하자,

     

    이를 arr2 = arr1으로 표현하면 arr2와 arr1은 동일한 객체를 가지고 있다고 볼 수 있는데

     

    이는 arr1와 arr2가 가리키는 주소 값이 같을 뿐 복사가 되었다고 할 수 없다.

     

    주소가 같기 때문에 arr1의 값을 바꿨을 때 arr2의 값 역시 함께 변경된다.

     

    import numpy as np
    
    arr1 = np.array([1,2,3,4])
    
    arr2 = arr1
    
    print(arr1 in arr2)
    
    True

     


     

    얕은 복사

     

     

    얕은 복사 방식으로는 view 메서드가 있는데 이 같은 경우 동일한 데이터를 보는 새 배열 객체를 만든다.

     

    다시 말해 주소는 다르지만 같은 데이터를 보고 있다는 말이기 때문에,

     

    이 역시 a값을 바꾸면 b값도 변경되어 얕은 복사라고 표현한다.

     

    rr1 = np.array([0,1,2,3,4])
    
    arr2 = arr1.view()
    print(arr1 is arr2)
    
    arr1[1] = 99 
    print(arr2)
    
    print(id(arr1))
    
    print(id(arr2))
    
    False
    [ 0 99  2  3  4]
    140260203212192
    140260203342144

     

    이처럼 값은 변동이 있지만 전혀 다른 주소 값을 가지고 있다.


     

    깊은 복사

     

     

    copy 메서드는 배열과 데이터의 완전한 복사본을 만들기 때문에 a값을 바꾼다 하더라도 b값은 변동이 없다.

     

    arr1 = np.array([1,2,3,4,5])
    arr2 = arr1.copy()
    print(arr1 is arr2)
    
    False
    
    arr1[1]=99
    print(arr2)
    print(id(arr1))
    print(id(arr2))
    
    [1 2 3 4 5]
    140260203023376
    140260203020336

     


     

    배열 연산

     

     

    numpy에서는 배 열간 기본적인 사칙 연산뿐만 아니라 평균, 표준 편차 등 다양한 수 계산을 도와주는데,

     

    사용법은 비교적 단순하지만 행렬의 구분을 확실하게 할 줄 알아야 유용하게 사용할 수 있다.

     

    사칙 연산
    
    arr1 = np.array([1,2])
    arr2 = np.ones(2, dtype=int)
    print(arr1+arr2)
    
    [2 3]
    
    print(arr1-arr2)
    [0 1]
    
    print(arr1*arr2)
    [1 2]
    
    print(arr1/arr2)
    [1. 2.]
    
    여기서 곱셈은 원소끼리의 곱이다.

     

    sum( )

     

    배열을 이루고 있는 원소의 합을 구할때 sum( )을 사용하고, 1차원 이상의 높은 차원을 가진 배열에서도 모두 작동하는데

     

    축 기준을 어디로 잡느냐에 따라 계산 값이 달라진다.

     

    arr = np.array([1,2,3,4])
    print(arr.sum())
    
    10
    
    arr = np.array([[1,1],[2,2]])
    print(arr.sum(axis=1))
    print(arr.sum(axis=0))
    
    [2 4]
    [3 3]

     

     

    max( ), min( )

     

     

    이름 그대로 주어진 축에 따라 최댓값, 최솟값을 반환한다.

     

    arr = np.array([[4,2,5,6,2,6],
                  [9,54,3,8,4,67],
                  [14,36,58,547,32,7]])
    
    print(arr.max(axis=0)) # 행(세로) 기준
    print(arr.max(axis=1)) # 열(가로) 기준
    
    [ 14  54  58 547  32  67]
    [  6  67 547]
    
    print(arr.max()) # 디폴트 전체 기준 가장 큰 값
    547
    arr = np.array([[4,2,5,6,2,6],
                  [9,54,3,8,4,67],
                  [14,36,58,547,32,7]])
    
    print(arr.min(axis=0)) # 행(세로) 기준
    print(arr.min(axis=1)) # 열(가로) 기준
    print(arr.min()) # 디폴트 전체 기준 가장 작은 값
    
    [4 2 3 6 2 6]
    [2 3 7]
    2

     

     

    평균 구하기

     

     

    mean( ) 메소드는 지정된 축을 따라 산술 평균을 구한다.

     

    arr = np.array([[4,2,5,6,2,6],
                  [9,54,3,8,4,67],
                  [14,36,58,547,32,7]])
    
    print(arr.mean(axis=0)) # 행(세로) 기준
    print(arr.mean(axis=1)) # 열(가로) 기준
    print(arr.mean()) # 디폴트 전체 값 평균
    
    [  9.          30.66666667  22.         187.          12.66666667
      26.66666667]
    [  4.16666667  24.16666667 115.66666667]
    48.0

     

     

    표준 편차

     

     

    std ( ) 메소드는 지정된 축을 따라 표준 편차 계산

     

    arr = np.array([[4,2,5,6,2,6],
                  [9,54,3,8,4,67],
                  [14,36,58,547,32,7]])
    
    print(arr.std(axis=0)) # 행(세로) 기준
    print(arr.std(axis=1)) # 열(가로) 기준
    print(arr.std()) # 디폴트 전체 표준 편차
    
    [  4.0824829   21.56128217  25.46893533 254.55975068  13.69509239
      28.52289529]
    [  1.67497927  26.04749935 193.59120733]
    122.78300642461345

     

    배열의 곱

     

     

    prod( ) 주어진 축의 배열 요소 곱 반환

     

    arr = np.array([[4,2,5,6,2,6],
                  [9,54,3,8,4,67],
                  [14,36,58,547,32,7]])
    
    print(arr.prod(axis=0)) # 행(세로) 기준
    print(arr.prod(axis=1)) # 열(가로) 기준
    print(arr.prod()) # 디폴트 전체 배열 곱
    
    [  504  3888   870 26256   256  2814]
    [      2880    3125952 3581738496]
    -4648021416080310272

     

    배열 간 내적 구하기

     

     

    dot( )는 두 배열의 내적을 구해준다.

     

    arr1 = np.eye(2)
    arr2 = np.ones((2, 2)) * 2
    print(arr1)
    print(arr2)
    print()
    print(arr1.dot(arr2))
    
    [[1. 0.]
     [0. 1.]]
    [[2. 2.]
     [2. 2.]]
    
    [[2. 2.]
     [2. 2.]]

     

    dot는 연결해서 사용할 수 있다는 특징을 가지고 있다.

     

    print(arr1.dot(arr2).dot(arr2))
    
    [[8. 8.]
     [8. 8.]]

     

     

    배열 간 행렬 곱

     

     

    np.matmul( ) 함수는 두 배열의 행렬 곱을 구해준다.

     

    arr1 = np.array([[1, 0],[0,1]])
    arr2 = np.array([[4, 1],[2,2]])
    print(np.matmul(arr1,arr2))
    
    [[4 1]
     [2 2]]

     


    알고 가기

     

     

    numpy의 특징인 브로드캐스트는 배열과 배열의 연산 과정에서 shape의 모양이 다르더라도

     

    연산을 위해 배열의 모양을 자동으로 맞춰 주는 기능을 말한다.

     

    이 기능이 있기 때문에 shape가 다른 배열의 연산, 배열과 스칼라의 연산이 가능하다.

     

    arr = np.array([1.0, 2.0])
    print(arr * 1.6)
    
    [1.6 3.2]

     

    위의 곱셈처럼 arr를 이루고 있는 요소는 두 개지만 곱셈을 하기 위해 1.6 요소 하나를 자동으로 추가하여

     

    배열의 크기를 맞춰 준다 이해하면 되겠다.

     

    이런 개념으로 shape이 다른 배열 간의 연산도 가능하지만,

     

    이 경우 shape이 같거나 차원 중 값이 1인 것이 존재해야만 가능하다. 이 조건이 충족되지 않는다면

     

    Value Error가 발생한다.

     


     

Designed by Tistory.