본문 바로가기
데이터 분석

넘파이

by 코낄2 2023. 11. 28.

1. 넘파이(Numpy)

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

설치: !pip install numpy

2. 주요 특징과 기능

  • 다차원 배열: 넘파이의 핵심 데이터 구조는 다차원 배열인 numpy.ndarray입니다. 다차원 배열은 1차원, 2차원, 3차원 등 다양한 차원을 가질 수 있습니다. 이 배열은 모든 요소가 동일한 자료형을 가지며, 배열의 차원을 나타내는 튜플로 표현됩니다. 이러한 배열은 파이썬 리스트보다 효율적인 연산을 제공합니다.
import numpy as np

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

# 2차원 배열
ndarr2 = np.array([[1,2,3], [4,5,6]])
print(ndarr2)
# [[1 2 3]
   [4 5 6]]
  • 리스트와 ndarray 변환
# 리스트를 ndarray로 변환
list1 = [1,2,3,4]
ndarr1 = np.array(list1)
print(ndarr1)
print(type(ndarr1))  # <class 'numpy.ndarray'>

# ndarray를 리스트로 변환
list2 = ndarr1.tolist()
print(list2)
print(type(list2))  # <class 'list'>
  • ndarray의 데이터 타입
ndarr1 = np.array([1, 2, 3, 4])
print(ndarr1)  # [1 2 3 4]
print(type(ndarr1[1]))  # <class 'numpy.int64'>

** type이 맞지 않아서 자동 변환 될 때는 type을 제일 큰 타입(메모리를 더 많이 차지하는 타입)으로 변경한다.

ndarr2 = np.array([1,2, 3.14 ,4])  # int, int, float, int
print(ndarr2)  # [1.   2.   3.14 4.  ]
print(type(ndarr2[1]))  # <class 'numpy.float64'>


ndarr3 = np.array([1, 2, 3.14, True]) # 모든 요소가 float로 변경됨
print(ndarr3)  # [1.   2.   3.14 1.  ]  << True는 1.0으로 변경
print(type(ndarr3[1]))  # <class 'numpy.float64'>


ndarr4 = np.array(['1', 2, 3.14, True]) # 모든 요소가 문자열로 변경됨
print(ndarr4)   # ['1' '2' '3.14' 'True']
print(type(ndarr4[1]))  # <class 'numpy.str_'>

**변경 할 type을 명시해놓기

ndarr3 = np.array([1, 2, 3.14, True], dtype = int)
# 모든 요소를 int로 변경
print(ndarr3)   # [1 2 3 1]
print(type(ndarr3[1])) # <class 'numpy.int64'>

ndarr4 = np.array(['1', 2, 3.14, True], dtype = int)
print(ndarr4)  # [1 2 3 1]
print(type(ndarr4[1]))  # <class 'numpy.int64'>
<< str이 숫자 형태이기 때문에 에러가 나지 않는다. >>
ndarr4 = np.array(['1', 2, 3.14, 'True'], dtype = int)

'True'를 int로 변경할 수 없기 때문에 오류발생!!
  • ndarray 인덱싱과 슬라이싱
ndarr1 = np.array(['🍓','🍉','🍎','🍊','🍌'])
print(ndarr1)  # ['🍓' '🍉' '🍎' '🍊' '🍌']
print(ndarr1.shape)  # (5,)
<< .shape : 차원을 알 수 있음. (5,) : 5개의 요소가 들어있음.>>

print(ndarr1[0]) 🍓
print(ndarr1[4]) 🍌
print(ndarr1[-1]) 🍌
# 슬라이싱
# ndarr1 = np.array(['🍓','🍉','🍎','🍊','🍌'])
print(ndarr1[0:3])  # ['🍓' '🍉' '🍎']
print(ndarr1[2:])   # ['🍎' '🍊' '🍌']
print(ndarr1[:3])   # ['🍓' '🍉' '🍎']

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

print(ndarr2d.shape) # (3, 4): 3행 4열
  • 행, 열 가져오기
# 0행 가져오기
print(ndarr2d[0])   # [1 2 3 4]
print(ndarr2d[0,])  # [1 2 3 4]
print(ndarr2d[0,:]) # [1 2 3 4]

# 0열 가져오기
print(ndarr2d[:,0]) # 행은 전부, 열은 0열만
# [1 5 9]
  • Fancy Indexing
ndarr1 = np.array([10, 15, 2, 8, 20, 90, 85, 44, 23, 32])
idx = [2, 5, 9]
print(ndarr1[idx]) # [ 2 90 32] 인덱스 2, 5, 9번 가져옴

ndarr2d = np.array([[1, 2, 3, 4],
                    [5, 6, 7, 8],
                    [9, 10, 11, 12]])
print(ndarr2d[[0,1],:]) # 0, 1 행, 열은 모두
# [[1 2 3 4]
 [5 6 7 8]]
  • Boolean Indexing
ndarr1 = np.array(['🍓','🍉','🍎','🍊','🍌'])
setValue = [True, False, True, True, False]
print(ndarr1[setValue]) # ['🍓' '🍎' '🍊']  # True인 값만 출력

setValue = [True, False, True]
print(ndarr1[setValue])
# 자리수가 안맞으면 에러발생
ndarr2d = np.array([[1, 2, 3, 4],
                    [5, 6, 7, 8],
                    [9, 10, 11, 12]])

print(ndarr2d>7) 
[[False False False False]
 [False False False  True]
 [ True  True  True  True]]
print(ndarr2d[ndarr2d>7])
[ 8  9 10 11 12]

3. 행렬 연산

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

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

print(a.shape, b.shape)
# (2, 3) (2, 3)
# 행렬 덧셈
print(a + b)
[[4 6 8]
 [3 5 7]]

# 행렬 뺄셈
print(a - b)
[[-2 -2 -2]
 [ 1  1  1]]
 
# 행렬 원소별 곱셈
print(a * b)
[[ 3  8 15]
 [ 2  6 12]]
  • 행렬 곱(Dot Product)
c = np.array([[1,2,3],
              [1,2,3],
              [2,3,4]])

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

print(a @ b) = print(np.dot(a, b))  # 에러
!! 맞닿는 shape가 같아야 함떨어져있는 shape가 결과 행렬이 됨
# (3, 3) (3, 2) 맞닿는 ( ,3)(3, ) 부분이 같아야 함.
# 결과는 (3, )( , 2)로 3*2가 나옴 (c의 행과 d의 열 곱)

print((1*1 + 2*3 + 3*5), (1*2 + 2*4 + 3*6)) 22 28
print((1*1 + 2*3 + 3*5), (1*2 + 2*4 + 3*6)) 22 28
print((2*1 + 3*3 + 4*5), (2*2 + 3*4 + 4*6)) 31 40

print(c@d)
[[22 28]
 [22 28]
 [31 40]]
print(np.dot(c, d))
[[22 28]
 [22 28]
 [31 40]]
전치행렬(Transpose Matrix)
: 각 원소의 행과 열을 바꾸는 연산
print(a)
[[1 2 3]
 [2 3 4]]
 
 print(a.T)
 [[1 2]
 [2 3]
 [3 4]]
# 역행렬: 원래 행렬과 곱했을 때 항등 행렬이 되는 행렬
# 모든 행렬이 역행렬을 갖는 것은 아니다.
# np.linalg.inv(a)
e = np.array([[1, 2], [3, 4]])
print(np.linalg.inv(e))
[[-2.   1. ]
 [ 1.5 -0.5]]

4. 순차적 값 생성

arr1 = range(1, 11)

for i in arr1:
    print(i, end=' ')  # 1 2 3 4 5 6 7 8 9 10
arr2 = np.arange(1, 11)
print(arr2) [ 1  2  3  4  5  6  7  8  9 10]

for i in arr2:
    print(i, end= ' ') # 1 2 3 4 5 6 7 8 9 10

5. 정렬

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

print(np.sort(ndarr1)) # 오름차순 정렬
[ 1  2  3  4  5  6  7  8  9 10]
print(ndarr1) # inplace 연산이 아니다!
[ 1 10  5  7  2  4  3  6  8  9]

print(np.sort(ndarr1)[::-1]) # 내림차순 정렬
[10  9  8  7  6  5  4  3  2  1]
ndarr2d = np.array([[11, 10, 12, 9],
                    [3, 1, 4, 2],
                    [5, 6, 7, 8]])

print(ndarr2d.shape) # (3, 4)
  • axis = 축.  0이면 행, 1이면 열
# 행정렬
print(np.sort(ndarr2d, axis = 0))
# 행기준 오름차순이 된다.
[[ 3  1  4  2]
 [ 5  6  7  8]
 [11 10 12  9]]
# 열 정렬
print(np.sort(ndarr2d))
[[ 9 10 11 12]
 [ 1  2  3  4]
 [ 5  6  7  8]]
print(np.sort(ndarr2d, axis=1))
[[ 9 10 11 12]
 [ 1  2  3  4]
 [ 5  6  7  8]]
 
 # 열 정렬 내림차순
 print(np.sort(ndarr2d, axis=1)[:,::-1])
 [[12 11 10  9]
 [ 4  3  2  1]
 [ 8  7  6  5]]
# 축의 마지막 방향
print(np.sort(ndarr2d, axis=-1))
[[ 9 10 11 12]
 [ 1  2  3  4]
 [ 5  6  7  8]]

'데이터 분석' 카테고리의 다른 글

가상 쇼핑몰 데이터 예제  (0) 2023.12.16
Matplotlib  (0) 2023.12.10
판다스3  (0) 2023.12.08
판다스2  (0) 2023.12.08
판다스1  (0) 2023.12.05