파이썬 딕셔너리를 이용한 희소 행렬(Sparse Matrix) 구현

희소 행렬(Sparse Matrix)은 대부분의 원소가 0인 행렬을 효율적으로 저장하는 방법입니다. 이러한 행렬을 일반적인 2차원 리스트로 저장하면 불필요하게 많은 메모리를 차지할 수 있습니다. 이를 해결하기 위해 딕셔너리 자료구조를 사용하여 0이 아닌 원소만 저장하는 방식으로 구현할 수 있습니다.

파이썬 딕셔너리를 활용한 희소 행렬은 행렬에서 값이 존재하는 위치만 기록해두어 메모리 사용을 줄이는 것이 특징입니다.

희소 행렬 구현 방법

딕셔너리를 사용하여 희소 행렬을 구현하는 기본적인 방법은 위치(좌표)를 키로, 해당 위치의 값을 값으로 저장하는 방식입니다. 예를 들어 (row, col): value 형식으로 값을 저장합니다.

구현 예제

아래 예제에서는 딕셔너리로 희소 행렬을 생성하고, 특정 원소를 추가, 조회, 출력하는 방법을 보여줍니다.

class SparseMatrix:
    def __init__(self, rows, cols):
        self.rows = rows
        self.cols = cols
        self.data = {}

    def set_value(self, row, col, value):
        if row >= self.rows or col >= self.cols:
            raise IndexError("Index out of bounds.")
        if value != 0:
            self.data[(row, col)] = value
        elif (row, col) in self.data:
            del self.data[(row, col)]

    def get_value(self, row, col):
        if row >= self.rows or col >= self.cols:
            raise IndexError("Index out of bounds.")
        return self.data.get((row, col), 0)

    def display(self):
        for row in range(self.rows):
            for col in range(self.cols):
                print(self.get_value(row, col), end=" ")
            print()

# 예제 사용
sparse_matrix = SparseMatrix(4, 5)
sparse_matrix.set_value(0, 1, 5)
sparse_matrix.set_value(1, 3, 8)
sparse_matrix.set_value(3, 4, 3)

print("희소 행렬 출력:")
sparse_matrix.display()

코드 설명

  1. 초기화: SparseMatrix 클래스는 rowscols를 받아 행렬 크기를 설정하고, data라는 딕셔너리를 초기화합니다.
  2. 값 설정: set_value 메서드는 (row, col) 위치에 값을 저장하며, 값이 0이면 해당 위치를 data에서 제거합니다.
  3. 값 조회: get_value 메서드는 (row, col) 위치의 값을 반환하며, 값이 없는 경우 0을 반환합니다.
  4. 행렬 출력: display 메서드는 전체 행렬을 출력합니다. 없는 값은 자동으로 0으로 채워서 출력됩니다.

출력 결과

희소 행렬 출력:
0 5 0 0 0
0 0 0 8 0
0 0 0 0 0
0 0 0 0 3

희소 행렬의 활용 예시

이와 같은 희소 행렬은 그래프의 인접 행렬 표현, 데이터 과학에서 희소 데이터를 다룰 때, 그리고 기계 학습에서 고차원 특성 데이터를 효율적으로 저장하고 계산하는 데 유용하게 사용됩니다.

희소 행렬(sparse matrix)은 대부분의 원소가 0인 행렬을 의미합니다. 이러한 행렬은 메모리 사용을 최적화하고, 계산 효율성을 높이기 위해 주로 사용됩니다. 희소 행렬은 다양한 분야에서 활용되며, 특히 데이터 과학, 머신러닝, 자연어 처리 등에서 자주 사용됩니다.

희소 행렬의 특징

  1. 메모리 절약: 대부분의 값이 0인 행렬에서는 0을 저장할 필요가 없으므로 메모리를 절약할 수 있습니다.
  2. 효율적인 연산: 연산할 때 0 값은 무시할 수 있기 때문에 계산 속도가 빨라질 수 있습니다.
  3. 구조적 표현: 희소 행렬을 효과적으로 표현하기 위한 다양한 데이터 구조가 존재합니다.

희소 행렬의 표현 방법

  1. 리스트(List):

    • 2차원 리스트로 행렬을 표현할 수 있지만, 메모리 효율성이 떨어집니다. 일반적으로는 0이 아닌 값만 저장하는 방식으로 표현합니다.
    # 희소 행렬 예시
    sparse_matrix = [
        [0, 0, 3, 0],
        [0, 0, 0, 0],
        [1, 0, 0, 0],
        [0, 4, 0, 0]
    ]
  2. 좌표 형식 (Coordinate List, COO):

    • 비어 있지 않은 원소의 위치와 값을 저장합니다. 각 비어 있지 않은 원소에 대해 (행 인덱스, 열 인덱스, 값)을 저장합니다.
    # COO 형식 예시
    row_indices = [0, 2, 3]  # 행 인덱스
    col_indices = [2, 0, 1]  # 열 인덱스
    values = [3, 1, 4]       # 값
    
    # 각 원소 (행, 열, 값)
    sparse_matrix_coo = list(zip(row_indices, col_indices, values))
  3. 압축 희소 행렬 (Compressed Sparse Row, CSR):

    • 값, 열 인덱스, 행 포인터를 저장하여 메모리 사용을 최적화합니다. CSR은 행렬 연산에서 빠른 성능을 제공합니다.
    from scipy.sparse import csr_matrix
    
    # 4x4 희소 행렬 생성
    data = [3, 1, 4]
    row_indices = [0, 2, 3]
    col_indices = [2, 0, 1]
    sparse_matrix_csr = csr_matrix((data, (row_indices, col_indices)), shape=(4, 4))
    
    print(sparse_matrix_csr)

예제: 리스트로 희소 행렬 표현

아래는 파이썬에서 리스트를 사용하여 희소 행렬을 표현하고, 비어 있지 않은 원소를 찾아 출력하는 예제입니다.

# 리스트로 희소 행렬 표현
sparse_matrix = [
    [0, 0, 3, 0],
    [0, 0, 0, 0],
    [1, 0, 0, 0],
    [0, 4, 0, 0]
]

# 비어 있지 않은 원소 출력
for i in range(len(sparse_matrix)):
    for j in range(len(sparse_matrix[i])):
        if sparse_matrix[i][j] != 0:
            print(f"원소 위치: ({i}, {j}) 값: {sparse_matrix[i][j]}")

이 코드를 실행하면 비어 있지 않은 원소의 위치와 값을 출력합니다.

요약

희소 행렬은 메모리 효율성을 높이고, 연산을 최적화하는 데 유용합니다. 다양한 표현 방법이 있으며, 프로젝트의 필요에 따라 적절한 방식을 선택하여 사용할 수 있습니다. 추가적인 질문이나 다른 희소 행렬 표현 방법에 대해 더 알고 싶으시면 말씀해 주세요!

+ Recent posts