Python/데이터분석

2024-05-22 넘파이

nomad06 2024. 5. 22. 12:49

1. 넘파이(Numpy)

  • 파이썬에서 사용되는 과학 및 수학 연산을 위한 강력한 라이브러리
  • 주로 다차원 배열을 다루는 데에 특화되어 있어, 데이터 분석, 머신러닝, 과학계산 등 다양한 분야에서 널리 사용
  • 넘파이 배열 C 언어로 구현되어 있어 연산이 빠르고 효율적
  • 넘파이 배열은 큰 데이터셋에서 수치 연산을 수행할 때 뛰어난 성능을 보이며, 메모리 사용을 최적화하고 효율적으로 관리
!pip install numpy
Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (1.25.2)

 

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

 

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

  • 넘파이의 핵심을 다차원 배열 ndarray
  • ndarray는 동일한 자료형을 가지는 원소들로 이루어져 있음
list1 = [1, 2, 3, 4]
list2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
print(list1)

print(list2)

print(type(list1))
print(type(list2))
 
print(type(list1[0]))
 
print(type(list2[0]))
 

 

import numpy as np

 

ndarry1 = np.array([1, 2, 3, 4])
print(ndarry1)
print(type(ndarry1))  # <class 'numpy.ndarray'>
print(type(ndarry1[0]))  # <class 'numpy.int64'>  => 넘파이가 만든 int

 

 

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

print(type(ndarry2))

 

print(type(ndarry2[0]))

 

 

 

2-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))

 

 

2-3. ndarray의 데이터 타입

  • 넘파이의 ndarray는 동일한 자료형을 가지는 원소들로 이루어져 있으며, 다양한 데이터 타입을 지원
list1 = [1, 2.14, 'Python', '🥰', True]
print(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]))

 

# 같은 타입만 저장함 => 전체가 실수형으로 바뀐다
ndarr2 = np.array([1, 2, 3.14, 4])
print(ndarr2)
print(type(ndarr2))
print(type(ndarr2[0]))  # <class 'numpy.float64'>
print(type(ndarr2[2]))  # <class 'numpy.float64'>

 

ndarr3 = np.array([1, 2, 3.14, True])
print(ndarr3)
print(type(ndarr3))
print(type(ndarr3[0]))  # <class 'numpy.float64'>
print(type(ndarr3[2]))  # <class 'numpy.float64'>
print(type(ndarr3[3]))  # <class 'numpy.float64'>  => True는 1이라서

 

# 문자로 다 바뀜
ndarr4 = np.array(['1', 2, 3.14, True])
print(ndarr4)
print(type(ndarr4))
print(type(ndarr4[0]))  # 'numpy.str_'>
print(type(ndarr4[2]))  # 'numpy.str_'>
print(type(ndarr4[3]))  # 'numpy.str_'>

 

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

 

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

 

# 에러 => '일'
ndarr4 = np.array(['일', 2, 3.14, True], dtype=int)
print(ndarr4)
print(type(ndarr4))
print(type(ndarr4[0]))  #
print(type(ndarr4[2]))  #
print(type(ndarr4[3]))  #

 

 

2-4. 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])

2-5. Fancy Indexding

  • 정수 배열이나 불리언 배열을 사용하여 배열의 일부를 선택하는 방법
  • 여러 개의 요소를 한 번에 선택하거나 조건에 맞게 선택할 수 있음
ndarr1 = np.array([10, 15, 2, 8, 20, 90, 85, 44, 23, 32])
idx = [2, 5, 9]
print(ndarr1[idx])
 
# 2차원 배열
ndarr2d = np.array([[1, 2, 3, 4],
                    [5, 6, 7, 8],
                    [9, 10, 11, 12]])
print(ndarr2d[[0, 1], :])
#             ------  --
#               행    열

2-6. Boolean Indexing

  • 불리언값으로 이루어진 배열을 사용하여 조건을 충족하는 원소만 선택하는 방법
ndarr1 = np.array(['🍓', '🍉', '🍌', '🍈', '🍎'])
sel = [True, False, True, True, False]
print(ndarr1[sel])  # True 해당만 가져옴
ndarr1 = np.array(['🍓', '🍉', '🍌', '🍈', '🍎'])
sel = [True, False, True]
print(ndarr1[sel])   # 갯수가 달라서 IndexError: boolean index 에러

 

# 비교연산자 쓰면 True, False가 되서
ndarr2d = np.array([[1, 2, 3, 4],
                    [5, 6, 7, 8],
                    [9, 10, 11, 12]])

print(ndarr2d[ndarr2d > 7])  # 7보다 큰 값만
print(ndarr2d > 7)   # 위 값이 나오는 원리

 

3. 행렬 연산

  • 넘파이에서는 다차원 배열인 ndarray를 사용하여 행렬 연산을 수행
  • 행렬 연산은 선형 대수와 관련이 깊어 데이터 과학, 머신러닝, 통게 등 다양한 분야에서 사용됨
ndarr1 = np.array([[1, 2, 3],
                   [2, 3, 4]])
ndarr2 = np.array([[3, 4, 5],
                   [1, 2, 3]])
print(ndarr1.shape)
print(ndarr2.shape)

 

# 행렬 덧셈
print(ndarr1 + ndarr2)
# 행렬 뺄셈
print(ndarr1 - ndarr2)
 
# 행렬 원소별 곱셈
print(ndarr1 * ndarr2)
# 행렬 곱 (Dot Product)
print(ndarr1 @ ndarr2)  # 에러
# ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 3)
# 행렬 곱의 조건: 맞닿는 shape가 같아야 함, 떨어져 있는 shape가 결과 행렬이 됨
# 예) (2, 3) @ (2, 3)  X
# 예) (3, 3) @ (3, 2)  O
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(ndarr3 @ ndarr4)
# 넘파이로
print(np.dot(ndarr3, ndarr4))
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))
# 전치 행렬
# 기존 행렬의 행과 열을 바꾼 새로운 행렬
# T
ndarr1 = np.array([[1, 2, 3],
                   [2, 3, 4]])
print(ndarr1)
print(ndarr1.T)

 

# 역행렬
# 주어진 정사각 행렬에 대한 곱셈 연산으로 단위 행렬을 얻을 수 있는 행렬
# 단위 행렬: 주대각선의 원소가 모두 1이고, 나머지 원소가 모두 0인 정사각형 행렬
arr = np.array([[1, 2], [3, 4]])
print(np.linalg.inv(arr))

print(arr @ np.linalg.inv(arr))

 

4. 순차적인 값 생성

arr1 = range(1, 11)
print(arr1)
print(type(arr1))
print(type(arr1[0]))

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

 

# 반환되는 값은 ndarray 형태
arr2 = np.arange(1, 11)
print(arr2)
print(type(arr2))
print(type(arr2[0]))

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

위 아래 결과 값은 같지만 타입이 조금 다름 

5. 정렬

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)
print(np.sort(ndarr2d, axis=0))  # 행정렬 => 행으로
print(np.sort(ndarr2d, axis=1))  # 열정렬  => 안에서
print(np.sort(ndarr2d, axis=1)[:,::-1]) # 열정렬 내림차순
print(np.sort(ndarr2d, axis=-1))  # 축의 마지막 방향  => 열방향 정렬과 같음 == axis=1

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

2024-05-28 상권별 업종 밀집 통계 데이터  (0) 2024.05.30
2024-05-27 가상 온라인 쇼핑몰 데이터  (0) 2024.05.27
2024-05-27 Matplotlib  (0) 2024.05.27
2024-05-24 판다스  (0) 2024.05.24
2024-05-23 판다스  (0) 2024.05.23