ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 4. Meta-data of ndarrays
    공부/likelion 2021. 9. 29. 20:00

     

    메타인지를 아십니까?

    한 때 메타인지라는 단어가 유행한 적이 있었다.

    메타인지란, 인지에 대한 한 차원 더 높은 고차원에 대한 생각으로,
    자기 자신의 인지에 대해 어떤 것을 알고, 어떤 것을 모르는지를 일컫는 말이다. 

    그렇다면 이와 연결해서 메타 데이터는 무엇일까?
    데이터에 대한 데이터, 즉 우리가 선언한 데이터에 대하여 관련된 정보를 일컫는 말이다.
    우리가 다루는 것은 ndarray, 즉 배열이니 해당되는 배열의 차원, 형태, 축, 요소 등등을 가리킨다. 

    즉 포스팅에서는 메타 데이터, 즉 데이터에 대한 데이터에 대한 설명을 하는 함수들에 대하여 다룬다. 

    포스팅에서 다룰 함수들은 다음과 같다.

    • ndarray.ndim
    • ndarray.shape
    • ndarray.size
    • ndarray.dtype
    • ndarray.itemsize
    • ndarray.nbytes

    1. ndim

    먼저 ndim들이 어떤 기능을 하는지 알아보기 위해 데이터를 만들어보자. 

    각각 스칼라, 1차원, 2차원, 3차원 텐서이다. 

    scalar_np = np.array(3.14)
    vector_np = np.array([1, 2, 3])
    matrix_np = np.array([[1, 2], [3, 4]])
    tensor_np = np.array([[[1, 2, 3], [4, 5, 6]],[[11, 12, 13], [14, 15, 16]]])
    # ndim = 해당 객체의 dimension, 즉 차원을 나타낸다. 
    print(scalar_np.ndim)
    print(vector_np.ndim)
    print(matrix_np.ndim)
    print(tensor_np.ndim)

    간단하다. 스칼라는 상수값이므로 0차원, 나머지는 각각 차원에 맞는 값을 출력한다.

    1. shape (관련 함수 : ndarray.reshape, ndarray.resize ndarray.flatten, ndarray.ravel)

    # shape = 해당 객체의 차원을 나타낸다. 표기되는 순서는 3차원을 기준으로 z,y,x 순.
    print(scalar_np.shape) 
    print(vector_np.shape)
    print(matrix_np.shape)
    print(tensor_np.shape)
    print(type(tensor_np.shape))

    shape와 ndim을 비교해보면, np.ndim 함수는 len(shape)와 같은 것을 알 수 있다.
    스칼라의 경우 상수 값만 존재하기 때문에, shape를 통해 차원을 찍어봐도 공란으로 나오는 것을 알 수 있다. 
    또한 shape는 튜플 형태로 데이터를 반환한다.

    2. size

    #size = 차원의 크기를 나타낸다. 
    #크기란, 해당 객체 안의 차원 안에 있는 원소를 포함하여 총 얼마나 원소가 들어갈 공간이 있는지를 나타낸다.
    
    S = np.ones(shape=(10, ))
    V = np.ones(shape=(3, 4))
    M = np.ones(shape=(3, 4, 5))
    T = np.ones(shape=(2, 3, 4, 5, 6))
    
    print(S.size)
    print(V.size)
    print(M.size)
    print(T.size)

    결과를 보면 어느 정도 유추할 수 있겠지만
    각 shape의 값을 서로 곱한 값이 size와 동일하다.

    예외로, 공간만 만들라고 선언하면 어떻게 나타날까?
    이런 걸 만들어주는 함수는 없나?

    a = np.array([[],[]])
    print(a.ndim)
    print(a.size)

    작동은 잘 된다.

    3. dtype (dtype 바꿔주기 : ndarray.astype)

    우선 ndarray에는 다음과 같은 자료형이 있다[1]

    int 및 uint의 자료형
    실수 자료형
    복소수 자료형

     

    그래서 해당 ndarray 객체를, dtype 함수를 이용해 확인할 수 있다

    a = np.arange(10)
    b = np.arange(3.14)
    c = np.array(-10,dtype = np.uint32)
    d = np.array(-10,dtype = np.int32)
    
    print(a.dtype)
    print(b.dtype)
    print(c, c.dtype)
    print(d, d.dtype)

    uint의 경우 음수라고 하더라도 unsigned로 취급되어 비트 연산을 사용하여 변환 처리하는 것을 볼 수 있다.
    0x7FFFFFFF +1 +x 이므로 4294967295 + 1 +(-10) = 4294967295-9 = 4294967286
    양수에서 저것보다 더 큰 수는 long으로 처리된다.

    따라서 우리가 가진 원소가 저것보다 더 큰 수일 경우에는
    파이썬의 특성상 남아있는 가용 메모리를 수 표현에 끌어다 쓸 수 있기 때문에(그것도 자동으로)[2]
    메모리 부족에 시달리는 데이터 분석의 특성상 단순한 숫자 표현 때문에 처리 간 OOM가 생길 수도 있을 것이다.
    그러면 어떻게 해야 될까? 해당 값들을 범주형으로 처리하거나,
    저 값에 가까운 값일수록 이상치가 아닐지 판단하는 태도가 필요할 것 같다.


    4. itemsize

    배열이 가지고 있는 요소, 즉 item의 크기를 가리킨다. 8bit = 1byte를 까먹지 말자.

    complex128은 실수부와 허수부에 각각 float64가 적용되므로 저렇게 출력된다

    x = np.array([1,2,3], dtype=np.float64)
    y = np.array([1,2,3], dtype=np.float32)
    z = np.array([1,2,3], dtype=np.float16)
    a = np.array([1,2,3], dtype=np.complex128)
    
    
    print(x.itemsize)
    print(y.itemsize)
    print(z.itemsize)
    print(a.itemsize)

    또한 배열의 크기(size) * 요소의 크기(itemsize)를 곱하면 해당 byte를 알 수 있는데,

    그렇다면 이 연산을 해주는 건 없을까?

    5. nbytes

    그게 바로 nbytes다.

    x = np.array([1,2,3], dtype=np.float64)
    
    print(x.itemsize * x.size)
    print(x.nbytes)

     

    6. 참고자료

    [1] https://kongdols-room.tistory.com/53?category=796900 

     

    NumPy의 데이터 타입(자료형), 관련된 함수 - NumPy(2)

    참고 자료 https://docs.scipy.org/doc/numpy/user/basics.types.html 파이썬 버전 3.7 기준 NumPy 버전 1.15 기준 본 포스팅에선 NumPy의 주요 자료형인 정수(int), 부호없는 정수(uint), 실수(float), 복소수(c..

    kongdols-room.tistory.com

    [2] https://mortada.net/can-integer-operations-overflow-in-python.html

     

    Can Integer Operations Overflow in Python? — Random Points

    We can see that it takes 28 bytes before we get to $2^{30}$ where python allocates 4 more bytes to store larger integers. Certainly not the most compact representation, as a raw 64-bit array (i.e. 8 bytes) could do the job with fixed-precision. However we

    mortada.net

     

    '공부 > likelion' 카테고리의 다른 글

    6. Element-wise Operations and Broadcasting  (0) 2021.10.01
    5. Changing ndarrays  (0) 2021.09.30
    3. making ndarray  (0) 2021.09.28
    2. Objects and ndarrays  (0) 2021.09.28
    1. DLGs(Digital Logic Gates)  (0) 2021.09.15
Designed by Tistory.