인공지능/데이터분석

넘파이

Ryuzy 2023. 11. 27. 03:57
728x90
반응형

1. 넘파이(Numpy)

넘파이(Numpy) 파이썬에서 사용되는 과학 수학 연산을 위한 강력한 라이브러리입니다. 주로 다차원 배열을 다루는 데에 특화되어 있어, 데이터 분석, 머신러닝, 과학 계산 다양한 분야에서 널리 사용됩니다. 넘파이 배열은 C 언어로 구현되어 있어 연산이 빠르고 효율적입니다. 특히 데이터셋에서 수치 연산을 수행할 뛰어난 성능을 보입니다. 또한 메모리 사용을 최적화하고 효율적으로 관리합니다.

# 설치
pip install numpy

 

import numpy as np

 

2. 넘파이의 주요 특징과 기능

1. 다차원 배열(N-dimensional array)

넘파이의 핵심은 다차원 배열인 ndarray입니다. ndarray는 동일한 자료형을 가지는 원소들로 이루어져 있습니다. 다차원 배열은 1차원, 2차원, 3차원 다양한 차원을 가질 있습니다.

list1 = [1, 2, 3, 4]
print(list1)
print(type(list1))
print(type(list1[0]))

list2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
print(list2)
print(type(list2))
print(type(list2[0]))

 

import numpy as np

ndarr1 = np.array([1, 2, 3, 4])
print(ndarr1)
print(type(ndarr1)) # <class 'numpy.ndarray'>
print(type(ndarr1[0])) # <class 'numpy.int64'>

ndarr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(ndarr2)
print(type(ndarr2)) # <class 'numpy.ndarray'>
print(type(ndarr2[0])) # <class 'numpy.ndarray'>

 

2. 리스트와 ndarray 변환

데이터 타입을 다른 데이터 타입으로 변환할 있습니다. 리스트에서 배열로의 변환은 np.array() 함수를 사용하고, 배열에서 리스트로의 변환은 tolist() 메서드를 사용합니다.

# 리스트를 ndarray로 변환
list1 = [1, 2, 3, 4]
ndarr1 = np.array(list1)
print(ndarr1)
print(type(ndarr1))

# ndarray를 리스트로 변환
list2 = ndarr1.tolist()
print(list2)
print(type(list2))

 

3. ndarray의 데이터 타입

넘파이의 ndarray 동일한 자료형을 가지는 원소들로 이루어져 있으며, 다양한 데이터 타입을 지원합니다.

list1 = [1, 3.14, 'Python', '😊', True]
print(list1)
print(type(list1))
print(type(list1[0]))
print(type(list1[1]))
print(type(list1[2]))
print(type(list1[3]))
print(type(list1[4]))

ndarr1 = np.array([1, 2, 3, 4])
print(ndarr1)
print(type(ndarr1))
print(type(ndarr1[0]))
print(type(ndarr1[1]))
print(type(ndarr1[2]))
print(type(ndarr1[3]))

 

ndarr2 = np.array([1, 2, 3.14, 4])
print(ndarr2)
print(type(ndarr2))
print(type(ndarr2[0]))
print(type(ndarr2[1]))
print(type(ndarr2[2]))
print(type(ndarr2[3]))

ndarr3 = np.array([1, 2, 3.14, True])
print(ndarr3)
print(type(ndarr3))
print(type(ndarr3[0]))
print(type(ndarr3[1]))
print(type(ndarr3[2]))
print(type(ndarr3[3]))

ndarr4 = np.array(['1', 2, 3.14, True])
print(ndarr4)
print(type(ndarr4))
print(type(ndarr4[0]))
print(type(ndarr4[1]))
print(type(ndarr4[2]))
print(type(ndarr4[3]))

ndarr3 = np.array([1, 2, 3.14, True], dtype=int)
print(ndarr3)
print(type(ndarr3))
print(type(ndarr3[0]))
print(type(ndarr3[1]))
print(type(ndarr3[2]))
print(type(ndarr3[3]))

ndarr4 = np.array(['1', 2, 3.14, True], dtype=int)
print(ndarr4)
print(type(ndarr4))
print(type(ndarr4[0]))
print(type(ndarr4[1]))
print(type(ndarr4[2]))
print(type(ndarr4[3]))

 

4. ndarray 인덱싱과 슬라이싱

넘파이의 ndarray는 리스트와 유사하게 인덱싱과 슬라이싱을 지원합니다.

ndarr1 = np.array(['🍓', '🍉', '🍌', '🍒', '🍑'])
print(ndarr1)
print(ndarr1.shape)

# 인덱싱
print(ndarr1[0])
print(ndarr1[4])
print(ndarr1[-1])
print(ndarr1[-2])

# 슬라이싱
print(ndarr1[0:3])
print(ndarr1[2:])
print(ndarr1[:3])

 

# 2차원 배열
ndarr2d = np.array([[1, 2, 3, 4],
                    [5, 6, 7, 8],
                    [9, 10, 11, 12]])
print(ndarr2d)
print(ndarr2d.shape)

# 0행 가져오기
print(ndarr2d[0, :])
print(ndarr2d[0,])
print(ndarr2d[0])

# 0열 가져오기
print(ndarr2d[:, 0])

 

ndarr1 = np.array([10, 15, 2, 8, 20, 90, 85, 44, 23, 32])
idx = [2, 5, 9]
print(ndarr1[idx]) # ndarr1[[2, 5, 9]]

ndarr2d = np.array([[1, 2, 3, 4], 
                    [5, 6, 7, 8], 
                    [9, 10, 11, 12]])
print(ndarr2d[[0, 1], :])

 

ndarr1 = np.array(['🍓', '🍉', '🍌', '🍒', '🍑'])
sel = [True, False, True, True, False]
ndarr1[sel]

# sel = [True, False, True]
# ndarr1[sel]

ndarr2d = np.array([[1, 2, 3, 4],
                    [5, 6, 7, 8],
                    [9, 10, 11, 12]])

print(ndarr2d > 7)            
print(ndarr2d[ndarr2d > 7])

 

 

3. 행렬 연산

넘파이에서는 다차원 배열인 ndarray 사용하여 행렬 연산을 수행할 있습니다. 행렬 연산은 선형 대수와 관련이 깊어, 데이터 과학, 머신러닝, 통계 다양한 분야에서 사용됩니다.

 

※ 선형 대수

선형 대수는 벡터와 행렬을 사용해 공간과 변환을 다루는 수학의 한 분야입니다. 쉽게 말해, 여러 숫자를 체계적으로 배열한 벡터(리스트 같은 것)와 행렬(숫자가 격자로 배열된 표)을 이용해 데이터를 표현하고 조작하는 방법입니다. 선형 대수는 컴퓨터 그래픽스, 머신러닝, 물리학, 공학 등 다양한 분야에서 사용됩니다. 예를 들어, 사진에서 색상을 조정하거나, 로봇이 움직일 경로를 계산하거나, AI가 데이터를 분석하는 데도 선형 대수가 필요합니다.

a = np.array([[1, 2, 3],
              [2, 3, 4]])
b = np.array([[3, 4, 5],
              [1, 2, 3]])
print(a.shape, b.shape)

# 행렬 덧셈
print(a + b)

# 행렬 뺄셈
print(a - b)

# 행렬 원소별 곱셈
print(a * b)

# 행렬 나눗셈
print(a / b)

 

 

※ 행렬곱

행렬곱은 두 행렬을 곱해서 새로운 행렬을 만드는 연산으로, 데이터의 변환이나 계산에서 많이 사용됩니다. 행렬은 숫자를 격자로 배열한 것으로, 벡터나 데이터를 다루는 데 유용합니다.

 

  행렬곱의 규칙
1. 첫 번째 행렬의 열(가로 숫자 개수)과 두 번째 행렬의 행(세로 숫자 개수)이 같아야 합니다.
예: A가 2×3 행렬이고 B가 3×2 행렬이라면, A와 B를 곱할 수 있습니다.
2. 결과 행렬은 첫 번째 행렬의 행 개수 × 두 번째 행렬의 열 개수입니다.
예: A(2×3) × B(3×2) → 결과는 2×2 행렬.
3. 행렬곱은 첫 번째 행렬의 한 행과 두 번째 행렬의 한 열을 각각 곱한 뒤 더해서 계산합니다.

ndarr3 = np.array([[1, 2, 3],
                   [1, 2, 3],
                   [2, 3, 4]])
ndarr4 = np.array([[1, 2],
                   [3, 4],
                   [5, 6]])
print(ndarr3.shape)
print(ndarr4.shape)

print((1*1 + 2*3 + 3*5), (1*2 + 2*4 + 3*6))
print((1*1 + 2*3 + 3*5), (1*2 + 2*4 + 3*6))
print((2*1 + 3*3 + 4*5), (2*2 + 3*4 + 4*6))

print(ndarr3 @ ndarr4)
# 행렬 곱셈 또는 벡터 내적을 수행
np.dot(ndarr3, ndarr4)

 

 

4. 순차적인 값 생성

NumPy에서 np.arange() 함수는 일정한 간격으로 숫자들을 생성하는 사용됩니다. 함수는 Python 기본 range() 함수와 유사하지만, NumPy 배열을 반환하므로 수학적인 연산이 가능합니다.

arr1 = range(1, 11)
print(arr1)

for i in arr1:
    print(i, end=' ')
    
arr2 = np.arange(1, 11)
print(arr2)
print(type(arr2))

for i in arr2:
    print(i, end=' ')

 

 

5. 정렬

NumPy np.sort() 함수는 배열을 정렬하는 사용됩니다. 함수는 기본적으로 원래 배열을 변경하지 않고 정렬된 배열의 복사본을 반환합니다.

ndarr1 = np.array([1, 10, 5, 7, 2, 4, 3, 6, 8, 9])
print(ndarr1)

print(np.sort(ndarr1)) # 오름차순 정렬
print(ndarr1)

print(np.sort(ndarr1)[::-1]) # 내림차순 정렬

ndarr2d = np.array([[11, 10, 12, 9],
                    [3, 1, 4, 2],
                    [5, 6, 7, 8]])
print(ndarr2d.shape)

# 열 단위로 정렬. 각 열의 값들을 개별적으로 오름차순으로 정렬하며, 행(row)의 순서는 재배열
np.sort(ndarr2d, axis=0)
# 행(row) 단위로 정렬. 각 행의 원소들이 개별적으로 오름차순으로 정렬
np.sort(ndarr2d, axis=1)
# 행 단위로 정렬한 후, 각 행의 값을 역순으로 정렬하는 동작을 수행
np.sort(ndarr2d, axis=1)[:, ::-1]
# axis=1과 동일하게 동작. -1은 배열의 마지막 축을 기준으로 동작하라는 의미. 2차원 배열에서 마지막 축은 axis=1을 나타냄
np.sort(ndarr2d, axis=-1)
728x90
반응형