1. 자료형(dtype)

연산이 가능한 이유?
Numpy에서 배열의 연산이 가능한 이유는 원소들이 모두 같은 자료형이기 때문이다.

dtype 설명 dtype 설명
b bool i int
f float O object
U string(유니코드)    
  • np.array(a, dtype='')
    배열을 만들 때 자료형을 미리 설정할 수 있다.
  • 자료형을 알기 위해 type()을 썼던 것처럼 .dtype()을 통해 배열의 자료형을 알 수 있다.
a = np.array([1, 2.2, 3])
b = np.array([1, 2.2, 3], dtype='i')
c = np.array([1, 2.2, 3], dtype='f')
d = np.array([1, 2.2, 3], dtype='O')
e = np.array([1, 2.2, 3], dtype='U')
a > [1.  2.2 3. ] float64
b > [1 2 3] int32
c > [1.  2.2 3. ] float32
d > [1 2.2 3] object
e > ['1' '2.2' '3'] <U3

2. 벡터화 연산

벡터화 연산이란 같은 위치의 원소끼리 연산이 되므로,
연산하기 위해서는 벡터 또는 행렬의 크기가 같아야한다.

1) Math Function

  • import numpy as np
함수 설명
np.add(arr1, arr2) 같은 위치의 원소끼리 덧셈
np.multiply(arr1, arr2) 같은 위치의 원소끼리 곱셈
np.sqrt(x) 각 원소에 대해 $\sqrt{x}$
np.exp(x) 각 원소에 대해 $e^x$
np.log(x) 각 원소에 대해 $\log_e(x), x>0$
로그함수의 경우 밑의 값에 따라 np.log10(x), np.log2(x)를 사용할 수 있다.  
  • 그 외의 함수들은 다음을 참고하자. NumPy Manual

2) Inf / NaN

  • np.inf(): infinity(무한대)
    ex. $\lim\limits_{x\to \infty} e^x = \infty$, $1 / 0 = \infty$
  • np.nan(): Not a Number ex. $0/0$, $\log(-1)$
a = np.array([1])
b = np.array([0])

print('inf >', np.inf)
print('1/inf >', 1 / np.inf)
print('NaN >', np.nan)
print('log(-1) >', np.log(-1))
print('1/0 >', a/b)
print('0/0 >', b/b)
inf > inf
1/inf > 0.0
NaN > nan
log(-1) > nan
1/0 > [inf]
0/0 > [nan]

3) 스칼라 연산(브로드캐스팅)

  • 브로드캐스팅(Broadcasting)
    벡터 또는 행렬의 각 원소에 스칼라의 연산으로 계산된다.

\[ \begin{bmatrix} 1\\ 2\\ 3\\ 4 \end{bmatrix} \times 2 = \begin{bmatrix} 1\times 2\\ 2\times 2\\ 3\times 2\\ 4\times 2 \end{bmatrix} \]

  • 고차원에서 작은 차원의 행 또는 열이 같아도 적용될 수 있다.

\[ \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9\\ 10 & 11 & 12 \end{bmatrix} + \begin{bmatrix} 1\\ 2\\ 3\\ 4\end{bmatrix} = \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9\\ 10 & 11 & 12 \end{bmatrix} + \begin{bmatrix} 1 & 1 & 1\\ 2 & 2 & 3\\ 3 & 3 & 3\\ 4 & 4 & 4\end{bmatrix} \]

\[ \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9\\ 10 & 11 & 12 \end{bmatrix} + \begin{bmatrix} 1 & 2 & 3 \end{bmatrix} = \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9\\ 10 & 11 & 12 \end{bmatrix} + \begin{bmatrix} 1 & 2 & 3\\ 1 & 2 & 3\\ 1 & 2 & 3\\ 1 & 2 & 3 \end{bmatrix} \]

arr1 = np.arange(1,5)
arr2 = np.arange(1,13).reshape(4, 3)
arr3 = np.arange(1, 5).reshape(4, 1)
arr4 = np.arange(1, 4).reshape(1, 3)

arr1 * 2
arr2 + arr3
arr2 + arr4

4) 벡터 연산

  • 같은 위치에 있는 원소들끼리 대해 연산한다.
  • For문으로 각 원소들마다 연산을 하는 것보다 훨씬 빠르다.
    • For문
        %%time 
        arr1 = np.arange(1, 1001)
        arr2 = np.arange(1001, 2001)
      
        arr3 = np.zeros_like(arr1)
        for i in range(len(arr1)):
            arr3[i] = arr1[i] + arr2[i]
      
        Wall time: 2 ms
      
    • 배열의 연산
        %%time 
        arr1 = np.arange(1, 1001)
        arr2 = np.arange(1001, 2001)
      
        arr3 = arr1 + arr2 
      
        Wall time: 0 ns
      

5) 논리 연산

  • >, <, ==, != 등 논리 연산자도 같은 위치의 원소에 대해 적용된다.
  • np.all()은 논리 연산 결과가 모두 True일 때 True, 아니면 False를 반환한다.
arr1 = np.array([1, 3, 5, 4, 2])
arr2 = np.array([2, 3, 1, 4, 5])

arr1 == arr2
array([False,  True, False,  True, False])

6) 차원 축소 연산

  • 행 또는 열에 대해 합, 평균을 구하면 각 행 또는 열에 대해 하나의 숫자로 계산된다. 이러한 연산을 차원 축소(dimension reduction) 연산이라고 한다.
  • axis=0은 열, axis=1은 행에 대해 계산한다.
  • 표본에 대한 분산, 표준편차의 경우 ddof=1 옵션을 추가한다.
    ($s^2$: 분산, $s$: 표준편차)
    • $s^2 = \dfrac{1}{N}\sum\limits_{i=1}^N(x_i-\bar{x})^2,\quad s^2 = \dfrac{1}{N-1}\sum\limits_{i=1}^N(x_i-\bar{x})^2$
    함수 설명 함수 설명
    arr.min()
    np.min(arr)
    최솟값 arr.max()
    np.max(arr)
    최댓값
    arr.argmin()
    np.argmin(arr)
    최솟값 위치 arr.argmin()
    np.argmin(arr)
    최댓값 위치
    arr.sum()
    np.sum(arr)
    합계    
    arr.mean()
    np.mean(arr)
    평균 np.median(arr) 중앙값
    arr.var()
    np.var(arr)
    분산 arr.std()
    np.std(arr)
    표준편차
    np.quandtile(arr,perc)
    np.percentile(arr, perc)
    사분위수    
    '논리'.all()
    np.all('논리')
    논리가 모두
    True인가
    '논리'.all()
    np.any('논리')
    논리가 하나라도
    True인가
# 통계 1 - 합계
arr1 = np.arange(1,13).reshape(3,4)
arr1
arr1.sum()
arr1.sum(axis=0)        # 각 열에 대해 계산
arr1.sum(axis=1)        # 각 행에 대해 계산
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
78
array([15, 18, 21, 24])
array([10, 26, 42])
# 통계 2 - 사분위수
arr2 = np.arange(10)
arr2
np.quantile(arr2, [0.0, 0.25, 0.5, 0.75, 1])
np.percentile(arr2, [0, 25, 50, 75, 100])
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
array([0.  , 2.25, 4.5 , 6.75, 9.  ])
array([0.  , 2.25, 4.5 , 6.75, 9.  ])
# 논리 연산
arr1 = np.array([1, 3, 2, 4, 5])
arr2 = np.array([1, 2, 3, 4, 5])
arr3 = np.array([1, 3, 2, 4, 5])

print('arr1 == arr2 >', arr1 == arr2)
print('np.all(arr1 == arr2) >', (arr1 == arr2).all())
print('np.all(arr1 == arr3) >', (arr1 == arr3).all())
print('np.any(arr1 == arr2) >', (arr1 == arr2).any())
print('np.any(arr1 == arr3) >', (arr1 == arr3).any())
arr1 == arr2 > [ True False False  True  True]
np.all(arr1 == arr2) > False
np.all(arr1 == arr3) > True
np.any(arr1 == arr2) > True
np.any(arr1 == arr3) > True

3. 정렬

  • arr.sort() 또는 np.sort(arr)로 정렬할 수 있다.
    arr.sort()은 배열 arr의 값이 바뀌고, 출력되지 않는다.
    np.sort(arr)는 바뀌지 않고 출력된다.
  • arr.argsort() 또는 np.argsort(arr)로 원소의 순서(rank)를 알 수 있다.
    해당 자리에 와야할 원소의 현재 위치를 반환한다.
  • axis=0은 열, axis=1은 행에 대해 정렬한다.
    지정하지 않으면 가장 안쪽의 차원에 대해 정렬한다.
arr1 = np.array([[13, 24, 3, 54],
                 [24, 31, 54, 2],
                 [14, 1, 35, 21]])

arr1
np.sort(arr1, axis=0)
np.sort(arr1, axis=1)

arr1
np.sort(arr1, axis=1)
np.argsort(arr1, axis=1)

댓글남기기