1. 벡터

1-1. 벡터는 1행 또는 1열로 이루어진 1차원 배열

import numpy as np

vector_row=np.array([1,2,3])    # 1행으로 이루어진 행벡터
vector_column=np.array([[1],    # 1열로 이루어진 열벡터
                        [2],
                        [3]])

 

1-2. asarray함수를 사용하여 배열을 만들수 있음

import numpy as np

new_row=np.asarray([1,2,3])    # np.array와 똑같이 1행으로 이루어진 행벡터 생성

 

np.asarray(넘파이 배열)은 새로운 배열 생성X

np.array(넘파이 배열)은 새로운 배열 생성

# array 사용

vector_row=np.array([1,2,3])    # 1행으로 이루어진 행벡터
new_row=np.array(vector_row)    # array의 copy 매개변수는 배열을 복사할지 선택, 
                                # 기본값은 True이므로 new_row에는 vector_row의 복사본 저장
                                
new_row[0]=10   # new_row의 첫번째 값 변경
print('new_row:',new_row)
print('vector_row:',vector_row)

### 결과 ###
new_row: [10,2,3]     # 복사본인 자기 자신에게만 영향을 주고
vector_row: [1,2,3]   # 원래 배열에는 영향을 주지 않음


# asarray 사용

new_row=np.asarray(vector_row)    # asarray는 새로운 배열을 생성하지 않고 원래의 배열 그 자체가 됨

new_row[0]=10   # new_row의 첫번째 값 변경
print('new_row:',new_row)
print('vector_row:',vector_row)

### 결과 ###
new_row: [10,2,3]      # 자기 자신에게 영향을 주고
vector_row: [10,2,3]   # 원래 배열에도 똑같이 영향을 줌

 

 

 

2. 행렬

2-1. 1개 이상의 행과 열로 이루어진 2차원 배열

import numpy as np

matrix=np.array([[1,2],    # 3행 2열의 행렬
                 [1,2],
                 [1,2]])

matrix_object=np.mat([[1,2],    # 3행 2열의 행렬, numpy의 행렬에 특화된 데이터 구조
                      [1,2],
                      [1,2]])

np.array()를 사용해 행렬 생성

np.mat가 행렬에 특화되어 있긴 하지만

   -numpy의 표준 데이터 구조는 배열이고

   -대부분의 넘파이 함수는 행렬 객체가 아닌 배열을 반환하므로

np.mat()보다는 np.array()를 사용

 

 

2-2. 희소행렬

데이터에서 0이 아닌 값이 매우 적을 때 이 데이터를 효율적으로 표현하는 방법

0이 아닌 값의 행과 열의 번호와 그 값만 저장됨

import numpy as np
from scipy import sparse

matrix=np.array([[0,0],
                 [0,1],
                 [3,0]])

matrix_sparse=sparse.csr_matrix(matrix)
print(matrix_sparse)

### 결과 ###
(1,1) 1    # 두번째 행, 두번째 열의 값 1
(2,0) 3    # 세번째 행, 첫번째 열의 값 3

위에서 사용한 것은 CSR(Compressed Sparse Row)이고

이외에도 CSC(Compressed Sparse Column), 리스트의 리스트, 키의 딕셔너리 등 여러 종류의 희소 행렬이 존재

가장 좋은 희소 행렬은 없고 각 희소 행렬 사이의 유의미한 차이를 통해 어떤 것을 적용하면 좋을 지 결정

    -키의 딕셔너리(Dictionary of Keys, DOK): 행렬에서 0이 아닌 값의 (행번호, 열번호)를 키, 행렬값을 값으로 하는 딕셔너리

    -리스트의 리스트(List of lists, LIL): 링크드 리스트 알고리즘 이용하여 추가와 삭제가 용이하지만 CSR과 CSC에 비해 메모리 낭비

    -좌표 리스트(Coordinate list, COO): (행, 열, 값)의 튜플로 저장, 임의 엑세스 시간을 향상시키기 위해 행 인덱스→열 인덱스 순으로 정렬 가능, 점진적 행렬 구성에 유용

    -CSR: 가로 순서대로 재정렬(행에 관해 정리 압축)

        →데이터(A): 0이 아닌 행렬 값과 값의 (행 번호, 열 번호)가 저장

        →열 인덱스 값(JA): 0행에서 값이 있는 열은 0, 3

                                          1행에서 값이 있는 열은 2, 4

                                          2행에서 값이 있는 열은 1

                                          3행에서 값이 있는 열은 2, 4

        →행 압축 정보(IA): (최초 시작행 번호, 시작행에 있는 데이터 개수, 두번째 행까지 데이터 누적 개수,..., 마지막행까지 데이터 누적 개수)

 

    -CSC: 열에 관해 정렬한 것, CSR과 저장 알고리즘은 동일, LIL에 비해 저장 메모리 70% 이상 줄일 수 있지만 추가와 삭제가 용이하지 않음

 

# toarray
print(matrix_sparse.toarray())

### 결과 ###
[[0,0],
 [0,1],
 [3,0]]    # 희소 행렬을 다시 밀집 배열로 변환
 
 
 # todense
 print(matrix_sparse.todense())
 
 ### 결과 ###
 matrix([[0,0],
         [0,1],
         [3,0]])    # 희소 행렬을 np.matrix 객체로 변환

 

 

2-3. 벡터화 연산

배열의 여러 원소에 어떤 함수 적용하기

import numpy as np

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

# 100을 더하는 함수
add_100=lambda i:i+100

# 함수를 np.vectorize(함수)를 통해 벡터화 시킴
vectorized_add_100=np.vectorize(add_100)

# 행렬에 벡터화된 함수를 적용시키면 행렬의 모든 원소에 함수 적용
vectorized_add_100(matrix)

### 결과 ###
array([[101,102,103],
       [104,105,106],
       [107,108,109]])

벡터화 연산은 기본적으로 for 루프를 구현한 것이므로 성능이 향상되지는 않음

 

 

2-4. 브로드캐스팅

넘파이 배열이 차원이 달라도 배열간 연산을 수행할 수  있음을 이용한 브로드캐스팅을 사용하면 더 간단하게 배열의 각 원소에 연산 적용 가능

# 1. 모든 원소에 100을 더함
matrix+100

### 결과 ###
array([[101,102,103],
       [104,105,106],
       [107,108,109]])


# 2. 행을 따라 더해짐
matrix+[100,100,10]

### 결과 ###
array([[101,102,13],
       [104,105,16],
       [107,108,19]])


# 3. 열을 따라 더해짐
matrix+[[100],[100],[10]]

### 결과 ###
array([[101,102,103],
       [104,105,106],
       [17,18,19]])

 

'Python > 기본문법' 카테고리의 다른 글

데이터 랭글링 (2)  (0) 2023.06.26
데이터 랭글링 (1)  (0) 2023.06.23
데이터 적재  (0) 2023.06.22
Numpy로 배열, 벡터, 행렬 이해하기 (3)  (0) 2022.10.20
Numpy로 배열, 벡터, 행렬 이해하기 (2)  (0) 2022.10.19

+ Recent posts