본문 바로가기
🛠️Skill/Python

[Python] Numpy란? 배열생성,차원변경/ 행렬곱(내적dot)/ 원소접근

by Istj_eff 2022. 10. 2.

1. Numpy 란?

배열, 행렬형식의 대량의 데이터를 다루기 위한 숫자 전문 라이브러리이다.

  • array : 동일데이터로 이루어진 데이터셋
  • ndarray : numpy의 n차원 배열객체. 하나의 데이터 타입만 가질 수 있다.
  • 차원
    • 1차원 축(행) : axis0 → Vector
    • 2차원 축(열): axis1 → Matrix
    • 3차원 축(채널): axis2 → Tensor(3차원이상)

 

✔️n차원 배열 예시

# 2차원배열은 [[두번 감싸준다고 생각하면됨!
a = np.array([[1,2],[3,4]]) 
[out]
array([[1, 2],
       [3, 4]])


# a의 형태와 type확인
print(a.ndim)          # 차원 확인 2
print(a.shape,a.dtype) # (2, 2) int32

b = np.array([[3,0],[0,6]])
[out]
array([[3, 0],
       [0, 6]])

a + b
[out]
array([[ 4,  2],
       [ 3, 10]])

a * b
[out]
array([[ 3,  0],
       [ 0, 24]])

a * 10  # 이게 브로드캐스트
[out]
array([[10, 20],
       [30, 40]])

 

✔️배열 생성

print(np.arange(10)) # 1씩 증가하는 1차원 배열(시작이 0부터)
## [0 1 2 3 4 5 6 7 8 9]

print(np.arange(5, 10)) # 1씩 증가하는 1차원 배열(시작이 5부터)
## [5 6 7 8 9]

print(np.zeros((2,2)))  # 영행렬 생성
## [[0. 0.]
##  [0. 0.]]

print(np.ones((2,3)))  # 유닛행렬
## [[1. 1. 1.]
##  [1. 1. 1.]]

print(np.full((2,3), 5)) # 모든 원소가 5인 2*3행렬
## [[5 5 5]
##  [5 5 5]]

 

✔️배열의 차원 변환

a = np.arange(20)
print(a)
## [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]

b = a.reshape((4,5))
print(b)
## [[ 0  1  2  3  4]
##  [ 5  6  7  8  9]
##  [10 11 12 13 14]
##  [15 16 17 18 19]]

 


2. 데이터 유형

1. 스칼라(Scala)

: 하나의 숫자로 이루어진 수
     ex) a=2

 

2. 벡터(Vector)

  • 동일한 데이터 유형으로 이루어진 한개 이상의 값들로 구성(하나의 column으로 되어있음) ex) (1,2,3)
  • 일정 규칙의 숫자 값들의 구성에 따라 차원이 결정 ex) n차원 벡터
  • 벡터 생성 : c(), seq(), sequence(), rep()
  • 덧셈, 뺄셈 가능
  • 내적(dot) : 곱셈 유사기능. 벡터의 길이가 같아야 가능. 결과값이 스칼라가 나오는 계산
    • 스칼라와 벡터의 곱 : 3x(1,2,3)=(3,6,9)
    • 스칼라와 벡터의 나누기 : (3,6,9)/3=(1,2,3)

✔️내적(dot) 코드예시

# 수치형으로 이루어진 벡터
v1 = c(3,10,12) 

# 3개의 문자형으로 이뤄진 벡터 (*따옴표 주의!)
v2 = c("Kim", "Lee", "Park") 

# 4개의 논리형으로 이뤄진 벡터 (*따옴표 없음 주의!)
v3 = c(True, False, False, False)

# 내적 dot
ar1 = np.array([10,20,30,40])
ar2 = np.array([1,2,3,3])
ardot=ar1.dot(ar2)
ardot

[out]
260

 

3. 텐서(Tensor) : 다차원 벡터 

✔️코드예시

arr = np.arange(0, 32)
print(len(arr))  # 결과는 32.
print(arr)

[out]
v = arr.reshape([4,2,4]) # 4개 행, 2개 열인 형태로 4개 덩어리 만들어라 -> 3차원 행렬의 텐서를 만들었다! 
v # 직관적으로 보면 [[[ 3번 지나서 텐서원소가 등장함 # 아래사진이 결과

row라는 x축  /  column이라는 y축  /  depth라는 z축으로 데이터가 표현되었기 때문

 

 

 

4. 행렬(2차원이 주력)

: 행과 열로 이루어진 데이터셋. 다차원 벡터  ex) 3x1

  1. 행렬곱@ (내적dot) : 행렬과 전치행렬의 행과 열을 서로 곱한값의 합
  2. 전치행렬: 전치(transpose). 행렬 대각선을 중심으로 뒤집은 형태

 

☑️ 전치행렬(transpose)사용해서 행렬곱 이해하기

  • transpose() : 전치행렬, 행렬 대각선을 중심으로 뒤집은 형태 세로방향의 행렬을 가로방향의 행렬로 변환된것, 혹은 그 반대. 벡터 혹은 행렬이라고 함
# 행렬곱 과정 하나씩
arr1=ar1.reshape(2,2)
arr1
=>array([[10, 20],
        [30, 40]])

arr2=ar2.reshape(2,2)
arr2
=>array([[1, 2],
        [3, 3]])

arr1[0]
=>array([10, 20])
arr2t = arr2.transpose()
arr2t
=>array([[1, 3],
        [2, 3]])

adot00 = arr1[0] * arr2.transpose()[0] # [0]행끼리 곱해서 출력
adot00
=>array([10, 60])

adot00 = np.sum(arr1[0] * arr2.transpose()[0]) # [0]행끼리 곱한값 더하기
adot00
=>70

adot01=np.sum(arr1[0]*arr2.transpose()[1]) # arr1의 [0]행과 arr2의 [1]행 곱한값 더하기
adot01
=>80

adot10=np.sum(arr1[1]*arr2.transpose()[0]) # arr1의 [1]행과 arr2의 [0]행 곱한값 더하기
adot10
=>150

adot11=np.sum(arr1[1]*arr2.transpose()[1]) # arr1의 [1]행과 arr2의 [1]행 곱한값 더하기
adot11
=>180
#행렬곱(행렬 내적) 결과**
ardot=arr1.dot(arr2)
ardot
=>array([[ 70,  80],
        [150, 180]])


# 이렇게 써도 동일
np.dot(arr1,arr2)


# 이렇게 써도 동일2
arr1@arr2

 

 

4. 원소 접근

☑️ 행,열,인덱스 접근

a = [51, 55, 14, 19, 0, 4]
a[1]
55

x = np.array([[51,55],[14,19],[0,4]])
x
array([[51, 55],
       [14, 19],
       [ 0,  4]])

x[0] # 0행 원소 접근
array([51, 55])

x[0][1] # 0행 1열 (0,1)위치의 원소
55

 

☑️ for문 접근

for row in x: # for문으로도 뽑을 수 있다
    print(row)
# [51 55]
# [14 19]
# [0 4]

X = x.flatten() # x를 1차원 배열로 변환(평탄화)
X
# array([51, 55, 14, 19,  0,  4])

X[np.array([0,2,4])] # 인덱스가 0,2,4인 원소 얻기
# array([51, 14,  0])

X > 15
# array([ True,  True, False,  True, False, False])

X[X>15]
# array([51, 55, 19])

 

☑️ for, lambda, numpy - 15이상인 숫자만 출력

a = [51, 55, 14, 19, 0, 4]
result=[]
for i in a:
    if i >= 15:
        result.append(i)
print(result)
# [51, 55, 19]


a = [51,55,14,19,0,4]
list(filter((lambda x : x >= 15), a))
# [51, 55, 19]


a2 = np.array(a)
list(a2[a2>=15])
# [51, 55, 19]

 

댓글