[BigData] Numpy 기본

2023. 3. 13. 21:43Computer Sciences/BigData

Numpy

행렬이나 대규모 다차원 배열을 쉽게 처리할 수 있도록 지원하는 파이썬 라이브러리이다.

파이썬 리스트 vs 넘파이 어레이

1. 선언 조건

  • 파이썬 리스트
    • 모든 타입을 가질 수 있다.
    • 2차원 이상 배열 구조에서 내부 배열의 원소 개수가 달라도 된다.
  • 넘파이 어레이
    • 숫자형 또는 문자열만 가질 수 있으며 숫자형과 문자열이 섞이면 모두 문자열로 전환
    • 2차원 이상 배열 구조에서 내부 배열의 원소 개수가 같아야 한다.
# 파이썬 리스트
a = [1, 2, 3, 'four', 'five'] # 1, 2, 3은 number, four five는 string
b = [[1], [2, 3], ['four', 'five']] # 파이썬 리스트는 원소 개수가 달라도 됨
# 넘파이 어레이
import numpy as np

arr = [1, 2, 3, 'four', 'five']
a = np.array(arr) # 1, 2, 3이 모두 문자열로 전환됨
b = np.array([[1, 2], [3, 4], [5, 6]]) # 넘파이 어레이는 원소 개수가 같아야 함

2. 연산

  • 파이썬 리스트는 덧셈 연산 시 항목을 이어 붙이는 concatenate 수행
  • 또한 리스트 간 다른 연산은 허용하지 않음
    • 곱셈은 자연수 곱셈만 가능, 원소 복사를 의미
a = [1, 3, 5]
b = [2, 4, 6]

a + b # [1, 3, 5, 2, 4, 6]
# 곱하기, 빼기, 나누기 불가능
a * 3 # [1, 3, 5, 1, 3, 5, 1, 3, 5]
  • 넘파이 어레이는 덧셈 시 항목 간 덧셈을 수행, 다른 사칙연산도 동일
  • 실수에 대한 사칙연산 과정도 원소 전체의 값에 대하여 수행 가능
a = np.array([1, 3, 5])
b = np.array([2, 4, 6])

a + b # [3, 7, 11]
a * b # [2, 12, 30]

a + 2 # [3, 5, 7]
a * 3 # [3, 9, 15]

3. 메소드

  • 두 자료구조에서 다루는 자료형이 다르기 때문에 지원하는 메소드도 다름
    • 파이썬 리스트에서는 mean, argmax, round 등 넘파이 어레이 메소드 지원 X
    • 넘파이 어레이에서는 append, remove, extend 등 파이썬 리스트 메소드 지원 X

4. 연산 속도

같은 연산을 수행하는 경우 넘파이 어레이가 훨씬 빠르다.

사용법

Array 생성

# numpy 라이브러리 임포트
import numpy as np

# numpy 배열 생성
l = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
na = np.array(l)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]
#  [9 10 11]]

# 범위 지정해서 생성
narg = np.arange(0, 12, 1) # 0부터 12까지 1 단위로 생성
print(narg) # [0 1 2 3 4 5 6 7 8 9 10 11]

# 0으로 초기화해서 생성
naz = np.zeros((4, 3))
# [[0 0 0]
#  [0 0 0]
#  [0 0 0]
#  [0 0 0]]

# 특정 array와 동일한 shape로 생성
nas = np.zeros(na.shape)
nas = np.zeros_like(na)
# [[0 0 0]
#  [0 0 0]
#  [0 0 0]
#  [0 0 0]]

Array 채우기

# numpy 라이브러리 임포트
import numpy as np

# 특정 값으로 채우기
nas.fill(1)
# [[1 1 1]
#  [1 1 1]
#  [1 1 1]
#  [1 1 1]]

# 특정 값 할당
nas[:] = 2
# [[2 2 2]
#  [2 2 2]
#  [2 2 2]
#  [2 2 2]]

# 특정 배열을 특정 모양으로 반복하여 할당
a = np.array([1, 2])

np.tile(a, 3)
# [1 2 1 2 1 2]

np.tile(a, (2, 2))
# [[1 2 1 2]
#  [1 2 1 2]]

Array 구조 변경

# numpy 라이브러리 임포트
import numpy as np

# 연산자의 replace/in-place 여부를 꼭 확인해야 함
# reshape는 replace가 아님
xrn = np.arange(0, 12, 1)
xrn.reshape(4, 3) # 원본은 변경되지 않음
print(xrn)
# [0 1 2 3 4 5 6 7 8 9 10 11 12]

xrn = xrn.reshape(4, 3) # 재할당으로 변경
print(xrn)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]
#  [9 10 11]]

# reshape의 마지막 파라미터는 -1도 가능하며 이 경우 자동으로 설정된다.
# 아래의 경우 12개의 원소를 4행으로 만드므로 (4, 3)의 array가 생성된다.
xs = np.arange(0, 12, 1).reshape(4, -1)
print(xs)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]
#  [9 10 11]]

# 12개의 원소를 dimension=2, 2행이므로 열은 3으로 자동으로 설정된다.
x = np.arange(0, 12, 1).reshape(2, 2, -1)
print(x)
# [[[0 1 2]
#        [3 4 5]]
#  [[6 7 8]
#   [9 10 11]]]

# 다차원 array를 1차원 array로 평평하게(flat) 변환한다.
xs = x.flatten()
print(xs)
# [0 1 2 3 4 5 6 7 8 9 10 11]

xs = x.reshape(-1)
print(xs)
# [0 1 2 3 4 5 6 7 8 9 10 11]

Slicing, Indexing

import numpy as np

x = np.arange(0, 12, 1).reshape(4, 3)
# 0번째 행의 1, 2번째 요소 슬라이싱
x_slicing = x[0, 1:3]
print(x_slicing)
# [1 2]

# 모든 행의 1, 2번째 요소 슬라이싱
x_slicing = x[:, 1:3]
print(x_slicing)
# [[1 2]
#  [4 5]
#  [7 8]
#  [10 11]

# 0, 2번째 행의 모든 요소 슬라이싱
x_slicing = x[::2, :]
print(x_slicing)
# [[0 1 2]
#  [6 7 8]]

# 0, 2번째 행의 0, 2번째 요소 슬라이싱
x_slicing = x[::2, ::2]
print(x_slicing)
# [[0 2]
#  [6 8]]

# 모든 요소 슬라이싱
x_slicing = x[:]
x_slicing = x[:,:]
print(x_slicing)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]
#  [9 10 11]]

Masking

import numpy as np

x = np.arange(0, 12, 1).reshape(4, 3)
# 요소의 값이 4보다 큰 경우 해당 요소는 true,
# 작은 경우 false로 하는 같은 shape의 array 반환
x_mask = x > 4
print(x_mask)
# [[False False False]
#  [False False True]
#  [True True True]
#  [True True True]]

# x에서 x_mask가 True인 값들로 이루어진 1차원 array 반환
x_masking = x[x_mask]
print(x_masking)
# [5 6 7 8 9 10 11]

Broadcasting

import numpy as np

x = np.arange(0, 12, 1).reshape(4, 3)

add = x + 3
print(add)
# [[3 4 5]
#  [6 7 8]
#  [9 10 11]
#  [12 13 14]]

mul = x * 3
# [[0 3 6]
#  [9 12 15]
#  [18 21 24]
#  [27 30 33]]

x1 = np.arange(0, 4, 1)
# [0 1 2 3]

x2 = np.arange(1, 3, 1)
# [1 2]

x3 = x1 * x2
# shape 문제로 브로드캐스팅 불가
# 

x2r = x2.reshape(2, 1)
# [[1]
#  [2]]

# dimension이 다른 경우 큰 쪽에 맞춰짐
x4 = x1 * x2r
# [[0 1 2 3]
#  [0 2 4 6]]

x5 = np.array([3])

x6 = x1 * x5
# [0 3 6 9]

행렬곱

import numpy as np

a = np.arange(1, 5).reshape(2, 2)
# [[1 2]
#  [3 4]]

b = np.arange(6, 10).reshape(2, 2)
# [[6 7]
#  [8 9]]

c = a * b
d = np.dot(a, b)
# [[6 14]
#  [24 36]]

Reduction

import numpy as np

x = np.arange(0, 12, 1).reshape(4, 3)

# 축을 모두 없애고 평균을 구해서 반환
xm = x.mean()
xm = np.mean(x)
# 5.5

# 열 평균 - axis=0
xc = x.mean(axis=0)
# [4.5 5.5 6.5]

# 행 평균 - axis=1
xr = x.mean(axis=1)
# [1 4 7 10]

Fortran-style order

import numpy as np

xf = np.arange(0, 12, 1).reshape(4, 3, order='F')
# [[0 4 8]
#  [1 5 9]
#  [2 6 10]
#  [3 7 11]]

Concatenation

import numpy as np

x = np.arange(0, 12, 1).reshape(4, 3)
y = np.arange(12, 24, 1).reshape(4, 3)

# 열 기준으로 concat
np.concatenate([x, y], axis=0)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]
#  [9 10 11]
#  [12 13 14]
#  [15 16 17]
#  [18 19 20]
#  [21 22 23]]

# 행 기준으로 concat
np.concatenate([x, y], axis=1)
# [[0 1 2 12 13 14]
#  [3 4 5 15 16 17]
#  [6 7 8 18 19 20]
#  [9 10 11 21 22 23]]

x1 = np.arange(0, 3, 1)
y1 = np.arange(3, 6, 1)

np.concatenate([x1, y1], axis=0)
# [0 1 2 3 4 5]

Copies and views

import numpy as np

# 복사본(copy)은 어떤 변경을 하더라도 원본에 영향을 끼치지 않는다.
arr = np.array([1, 2, 3, 4, 5])
copy = arr.copy()
arr[0] = 21

print(arr)
# [21 2 3 4 5]
print(copy)
# [1 2 3 4 5]

# 뷰(view)는 변경 시 원본에도 영향을 끼친다.
arr = np.array([1, 2, 3, 4, 5])
view = arr.view()
arr[0] = 32

print(arr)
# [32 2 3 4 5]
print(view)
# [32 2 3 4 5]

# original이나 copy는 다른 객체로부터 생성된 것이 아닌 base object
# view는 다른 객체로부터 생성된 것으로 view의 base object는 original array
arr = np.array([1, 2, 3, 4, 5])
print(arr.base)
# None

copy = arr.copy()
print(copy.base)
# None

print(copy.base is arr)
# False

view = arr.view()
print(view.base)
# [1 2 3 4 5]

print(view.base is arr)
# True

'Computer Sciences > BigData' 카테고리의 다른 글

[BigData] 데이터 시각화  (0) 2023.04.17
[BigData] 데이터 정규화  (0) 2023.04.17
[BigData] 데이터 이해  (1) 2023.04.17
[BigData] Pandas 기본  (4) 2023.03.14