chapter 1 : 03 넘파이 (p.13 ~ p.38)

    넘파이 (NumPy)

     

    1) 넘파이 개요

     

    array() : ndarray로 변환

    shape : ndarray의 크기, 즉 행과 열의 수를 튜플 형태로 가지며 이를 통해 ndarray 배열의 차원까지 알 수 있음

    import numpy as np
    
    arr1 = np.array([1, 2, 3])
    print("arr1 type:", type(arr1))
    print("arr1 형태:", arr1.shape)
    
    arr2 = np.array([[1, 2, 3], [2, 3, 4]])
    print("arr2 type:", type(arr2))
    print("arr2 형태:", arr2.shape)
    
    arr3 = np.array([[1, 2, 3]])
    print("arr3 type:", type(arr3))
    print("arr3 형태:", arr3.shape)
    # output
    
    arr1 type: <class 'numpy.ndarray'>
    arr1 형태: (3,)
    arr2 type: <class 'numpy.ndarray'>
    arr2 형태: (2, 3)
    arr3 type: <class 'numpy.ndarray'>
    arr3 형태: (1, 3)

     

     

    2) ndarray의 데이터 타입

     

    ndarray 내의 데이터 타입은 그 연산의 특성 상 같은 데이터 타입만 가능

    → 다른 데이터 유형이 섞여 있는 리스트를 ndarray로 변경하면 데이터 크기가 더 큰 데이터 타입으로 형 변환을 일괄 적용 

    list1 = [1, 2, 'test']
    array1 = np.array(list1)
    print(array1, array1.dtype)
    
    list2 = [1, 2, 3.0]
    array2 = np.arrya(list2)
    print(array2, array2.dtype)
    # output
    
    ['1' '2' 'test'] <U21
    [1. 2. 3.] float64

     

     

    astype() : ndarray 내 데이터값의 타입 변경

    array_int = np.array([1, 2, 3])
    array_float = array_int.astype('float64')
    print(array_float, array_float.dtype)
    # output
    
    [1. 2. 3.] float64

     

     

    3) ndarray를 편리하게 생성하기

     

    arrange() : 0부터 함수 인자 값 -1까지의 값을 순차적으로 ndarray의 데이터 값으로 변환

    array = np.arange(10)
    print(array)
    print(array.dtype, array.shape)
    # output
    
    [0 1 2 3 4 5 6 7 8 9]
    int64 (10,)

     

     

    zeros() : 튜플 형태의 shape 값을 입력하면 모든 값을 0으로 채운 해당 shape을 가진 ndarray 반환

    ones() :  튜플 형태의 shape 값을 입력하면 모든 값을 1으로 채운 해당 shape을 가진 ndarray 반환

    zero_array = np.zeros((3, 2), dtype ='int32')
    print(zero_array)
    print(zero_array.dtype, zero_array.shape)
    
    one_array = np.ones((3, 2)) #dtype을 정해주지 않으면 default로 float64
    print(one_array)
    print(one_array.dtype, one_array.shape)
    # output
    
    [[0 0]
     [0 0]
     [0 0]]
    int32 (3, 2)
    [[1. 1.]
     [1. 1.]
     [1. 1.]]
    float64 (3, 2)

     

     

    4) ndarray의 차원과 크기를 변경하는 reshape()

     

    reshape() : ndarray를 (row x column) 2차원 형태로 변환

    array1 = np.arange(10)
    print('array1\n', array1)
    
    array2 = array.reshape(2, 5) # ex (4,3) shape는 불가능
    print('array2\n', array2)
    
    array3 = array.reshape(5, 2)
    print('array3\n', array3)
    # output
    
    array1
     [0 1 2 3 4 5 6 7 8 9]
    array2
     [[0 1 2 3 4]
     [5 6 7 8 9]]
    array3
     [[0 1]
     [2 3]
     [4 5]
     [6 7]
     [8 9]]

     

    reshape은 인자로 -1을 적용하는 경우 가 많은데, -1을 인자로 사용하면 원래 ndarray와 호환되는 새로운 shape으로 변환

    array1 = np.arange(10)
    print('array1:', array1)
    
    array2 = array.reshape(-1, 5)
    print('array2 shape:', array2.shape)
    
    array3 = array.reshape(5, -1)
    print('array3 shape:', array3.shape)
    # output
    
    array1: [0 1 2 3 4 5 6 7 8 9]
    array2 shape: (2, 5)
    array3 shape: (5, 2)

     

     

    5) 넘파이의 ndarray의 데이터 세트 선택하기 - 인덱싱(indexing)

     

    ① 단일 값 추출

    : 해당하는 위치의 인덱스 값을 [ ] 안에 입력

    array1 = np.arange(start = 1, stop = 10)
    print('array1',array1)
    
    #단일값 추출
    value = array1[2]
    print('value:', value)
    
    # ndarray내의 데이터 수정
    array1[0] = 9
    array1[8] = 0
    print('array1:', array1)
    # output
    
    array1 [1 2 3 4 5 6 7 8 9]
    value: 3
    array1: [9 2 3 4 5 6 7 8 0]

     

    ② 슬라이싱

    : ':'을 이용해 연속 데이터를 추출함 → 시작인덱스에서 종료 인덱스-1 위치에 있는 데이터의 ndarray를 반환

    array1 = np.arange(start = 1, stop = 10)
    array2 = array1[0:3]
    print(array2)
    print(type(array2))
    # output
    
    [1 2 3]
    <class 'numpy.ndarray'>

     

    array1 = np.arange(start = 1, stop = 10)
    array2 = array1[:3]
    array3 = array1[3:]
    array4 = array1[:]
    
    print(array2)
    print(array3)
    print(array4)
    
    """
    # output
    
    [1 2 3]
    [4 5 6 7 8 9]
    [1 2 3 4 5 6 7 8 9]
    """

     

     

    * 2차원 ndarray에서 슬라이싱

    : 콤마(,)로 로우와 칼럼 인덱스를 지칭

    import numpy as np
    
    array1d = np.arange(start = 1, stop = 10)
    array2d = array1d.reshape(3, 3)
    print('array2d:\n', array2d)
    
    print('array2d[0:2, 0:2]\n', array2d[0:2, 0:2])
    print('array2d[1:3, 0:3]\n', array2d[1:3, 0:3])
    print('array2d[1:3, :]\n', array2d[1:3, :])
    print('array2d[:2, 1:]\n', array2d[:2, 1:])
    print('array2d[:2, 0]\n', array2d[:2, 0])
    # output
    
    array2d:
     [[1 2 3]
     [4 5 6]
     [7 8 9]]
    array2d[0:2, 0:2]
     [[1 2]
     [4 5]]
    array2d[1:3, 0:3]
     [[4 5 6]
     [7 8 9]]
    array2d[1:3, :]
     [[4 5 6]
     [7 8 9]]
    array2d[:2, 1:]
     [[2 3]
     [5 6]]
    array2d[:2, 0] #한 축에만 단일 값 인덱스 적용 가능
     [1 4]

     

     

    ③ 팬시 인덱싱

    : 리스트나 ndarray로 인덱스 집합을 지정하면 해당 위치의 인덱스에 해당하는 ndarray를 반환

    array1d = np.arange(start = 1, stop = 10)
    array2d = array1d.reshape(3, 3)
    
    array3 = array2d[[0,1], 2] #로우 축에 팬시 인덱싱, 칼럼 축에 단일 값 인덱싱
    print('array2d[[0,1],2] →', array3.tolist())
    
    array4 = array2d[[0,1], 0:2] 
    print('array2d[[0,1], 0:2] →', array4.tolist())
    
    array5 = array2d[[0,1]]
    print('array2d[[0,1]] →', array5.tolist())
    # output
    
    array2d[[0,1],2] → [3, 6]
    array2d[[0,1], 0:2] → [[1, 2], [4, 5]]
    array2d[[0,1]] → [[1, 2, 3], [4, 5, 6]]

     

    array2d [[0, 1], 2]

    1 2 3
    4 5 6
    7 8 9

     

    array2d[[0, 1], 0:2]

    1 2 3
    4 5 6
    7 8 9

     

    array2d[[0, 1]]

    1 2 3
    4 5 6
    7 8 9

     

     

    ④ 불린 인덱싱

    : 조건 필터링과 검색을 동시에 수행 가능

    array1d = np.arange(start = 1, stop = 10)
    
    array2 = array1d[array1d > 5] # if '추출값' > 5
    print(array2)
    # output
    
    [6 7 8 9]

     

    ndarray에 조건식을 붙이면 true, false로 이루어진 객체 반환

    array1d > 5
    # output
    
    # 5보다 큰 데이터가 있는 위치는 True, 그렇지 않은 경우 False
    array([False, False, False, False, False,  True,  True,  True,  True])

     

     

    6) 행렬의 정렬

     

    ① 행렬정렬

    np.sort() 원 행렬은 유지한 채 원 행렬의 정렬된 행렬을 반환

    ndarray.sort() 원 행렬 자체를 정렬한 형태로 변환

    import numpy as np
    
    org_array = np.array([3, 1, 9, 5])
    print('원본행렬:', org_array)
    
    # np.sort
    sort_array1 = np.sort(org_array)
    print('np.sort() 후 반환 행렬:', sort_array1)
    print('np.sort() 후 원본 행렬:', org_array)
    
    # ndarray.sort
    sort_array2 = org_array.sort()
    print('org_array.sort() 후 반환 행렬:', sort_array2)
    print('org_array.sort() 후 원본 행렬:', org_array)
    # output
    
    원본행렬: [3 1 9 5]
    np.sort() 후 반환 행렬: [1 3 5 9]
    np.sort() 후 원본 행렬: [3 1 9 5]
    org_array.sort() 후 반환 행렬: None
    org_array.sort() 후 원본 행렬: [1 3 5 9]

     

     

    ② 내림차순 정렬

    :  np.sort()[::-1]

    org_array = np.array([3, 1, 9, 5])
    sort_array1_desc = np.sort(org_array)[::-1]
    print(sort_array1_desc)

     

     

    ③ 정렬된 행렬의 인덱스 반환

    : np.argsort()

    org_array = np.array([3, 1, 9, 5])
    sort_indices = np.argsort(org_array)
    print(sort_indices)
    # output
    
    [1 0 3 2]

     

    넘파이의  ndarray는 실제 값과 그 값이 뜻하는 메타 데이터를 별도의 ndarray로 각각 가져야 한다. 예를 들어 John = 78, Mike = 95, Kate = 98 ...으로 활용하고자 한다면 name_array와 score_array 2개의 ndarray를 만들어야 한다.

     

    이떄 시험 성적순으로 학생 이름을 출력하고자 한다면 np.argsort(score_array)를 이용해 반환된 인덱스를  name_array에 팬시 인덱스로 적용해 추출할 수 있다.

     

    import numpy as np
    
    name_array = np.array(['John', 'Mike', 'Sarah', 'Kate', 'Samuel'])
    score_array = np.array([78, 95, 84, 98, 88])
    
    sort_indices_asc = np.argsort(score_array)
    print('성적 오름차순 정렬 시 score_array의 인덱스:', sort_indices_asc)
    print('성적 오름차순 정렬 시 name_array의 이름 출력:', name_array[sort_indices_asc])
    # output
    
    성적 오름차순 정렬 시 score_array의 인덱스: [0 2 4 1 3]
    성적 오름차순 정렬 시 name_array의 이름 출력: ['John' 'Sarah' 'Samuel' 'Mike' 'Kate']

     

     

    6) 선형대수 연산 - 행렬 내적과 전치 행렬 구하기

     

    ① 행렬 내적

    : np.dot()

    # a : 2*3 , b : 3*2 -> a와 b의 내적 결과: 2*2
    
    a = np.array([[1, 2, 3], 
                  [4, 5, 6,]])
    
    b = np. array([[7, 8],
                   [9, 10],
                   [11, 12]])
    
    result = np.dot(a, b)
    print(result)
    # output
    
    [[ 58  64]
     [139 154]]

     

     

    ② 전치 행렬 

    : np.transpose()

    a = np.array([[1, 2], 
                  [3, 4]])
    
    result = np.transpose(a)
    print(result)
    # output
    
    [[1 3]
     [2 4]]

     

    'Data Mining > ML' 카테고리의 다른 글

    chapter 1 : 04 데이터 핸들링 - 판다스 (p.39~)  (0) 2021.12.27

    댓글