2013-04-16 3 views
3

메모리에로드 될 때 1 기가비트를 차지할 상당히 큰 희소 행렬이 있습니다.큰 스파 스 매트릭스 저장 및 검색

항상 전체 매트릭스에 액세스 할 필요가 없으므로 일종의 메모리 매핑이 작동합니다. 그러나 numpy 나 spicy (익숙한 도구)를 사용하여 스파 스 매트릭스를 메모리 맵핑 할 수는 없습니다.

메모리에 쉽게 맞을 수 있지만 프로그램을 실행할 때마다로드해야한다면 고통이 될 것입니다. 아마도 그것을 실행 사이에 메모리에 유지하는 어떤 방법일까요?

그럼, 당신은 무엇을 제안합니까 : 1. 스파 스 매트릭스를 메모리 맵핑하는 방법을 찾으십시오. 2. 때마다 메모리에 전체 생각을로드하십시오 3.?

+0

매트릭스가 어떻게 저장 되나요? 행렬의 어느 부분을 동시에 메모리에로드하고 싶습니까? 묻는대로 귀하의 질문은 답변을 넓히는 방법입니다 ... – Jaime

답변

2

scipy support different kinds of sparse matrices. 그러나 당신은 메모리에 그것을 읽는 루틴을 써야 할 것입니다. 어떤 유형을 사용해야할지에 따라 달라집니다.

매트릭스가 매우 희박한 경우 struct 모듈을 사용하여 (row, column, value) 튜플을 디스크에 바이너리 데이터로 저장할 수 있습니다. 이렇게하면 디스크에 저장된 데이터를 더 작게 만들 수 있으며, 이식성이 문제가되지 않는다면 쉽게로드 할 수 있습니다.

당신은 다음과 같은 데이터를 읽을 수 있습니다 :

import struct 
from functools import partial 

fmt = 'IId' 
size = struct.calcsize(fmt) 

with open('sparse.dat', 'rb') as infile: 
    f = partial(infile.read, size) 
    for chunk in iter(f, ''): 
     row, col, value = struct.unpack(fmt, chunk) 
     # put it in your matrix here 
5

이 다음은 일반적인 개념으로 작동 할 수 있지만 당신은 많은 세부 사항을 파악해야 할 것 ... 먼저 자신을해야한다

>>> import scipy.sparse as sps 
>>> a = sps.rand(10, 10, density=0.05, format='csr') 
>>> a.toarray() 
array([[ 0.  , 0.46531486, 0.03849468, 0.51743202, 0.  ], 
     [ 0.  , 0.67028033, 0.  , 0.  , 0.  ], 
     [ 0.  , 0.  , 0.  , 0.  , 0.  ], 
     [ 0.  , 0.  , 0.  , 0.  , 0.9967058 ], 
     [ 0.  , 0.  , 0.  , 0.  , 0.  ]]) 
>>> a.data 
array([ 0.46531486, 0.03849468, 0.51743202, 0.67028033, 0.9967058 ]) 
>>> a.indices 
array([1, 2, 3, 1, 4]) 
>>> a.indptr 
array([0, 3, 4, 4, 5, 5]) 

그래서 a.data 비를 갖는다 : 0이 아닌 항목의 수, 길이의 하나의 행의 수를 더한 하나의 길이의 두 개의 어레이에 대한 모든 정보가 3 개 어레이에 저장된 CSR format, 익숙 0 개 항목, 행 주요 순서, a.indices은 0이 아닌 항목의 해당 열 인덱스를 가지며 a.indptr은 모든 행에 대한 데이터가 시작되는 다른 두 배열에 시작 인덱스가 있습니다. a.indptr[3] = 4a.indptr[3+1] = 5이므로, 네 번째 행의 0이 아닌 항목은 a.data[4:5]이고 열 인덱스는 a.indices[4:5]입니다.

그래서 당신은 디스크에서이 세 가지 배열을 저장하고 memmaps로 액세스하고 다음과 같이 다음 행이 N을 통해 해요 검색 할 수있는 수 :

ip = indptr[m:n+1].copy() 
d = data[ip[0]:ip[-1]] 
i = indices[ip[0]:ip[-1]] 
ip -= ip[0] 
rows = sps.csr_matrix((d, i, ip)) 

을 개념의 일반적인 증거로서 :

>>> c = sps.rand(1000, 10, density=0.5, format='csr') 
>>> ip = c.indptr[20:25+1].copy() 
>>> d = c.data[ip[0]:ip[-1]] 
>>> i = c.indices[ip[0]:ip[-1]] 
>>> ip -= ip[0] 
>>> rows = sps.csr_matrix((d, i, ip)) 
>>> rows.toarray() 
array([[ 0.  , 0.  , 0.  , 0.  , 0.55683501, 
     0.61426248, 0.  , 0.  , 0.  , 0.  ], 
     [ 0.  , 0.  , 0.67789204, 0.  , 0.71821363, 
     0.01409666, 0.  , 0.  , 0.58965142, 0.  ], 
     [ 0.  , 0.  , 0.  , 0.1575835 , 0.08172986, 
     0.41741147, 0.72044269, 0.  , 0.72148343, 0.  ], 
     [ 0.  , 0.73040998, 0.81507086, 0.13405909, 0.  , 
     0.  , 0.82930945, 0.71799358, 0.8813616 , 0.51874795], 
     [ 0.43353831, 0.00658204, 0.  , 0.  , 0.  , 
     0.10863725, 0.  , 0.  , 0.  , 0.57231074]]) 
>>> c[20:25].toarray() 
array([[ 0.  , 0.  , 0.  , 0.  , 0.55683501, 
     0.61426248, 0.  , 0.  , 0.  , 0.  ], 
     [ 0.  , 0.  , 0.67789204, 0.  , 0.71821363, 
     0.01409666, 0.  , 0.  , 0.58965142, 0.  ], 
     [ 0.  , 0.  , 0.  , 0.1575835 , 0.08172986, 
     0.41741147, 0.72044269, 0.  , 0.72148343, 0.  ], 
     [ 0.  , 0.73040998, 0.81507086, 0.13405909, 0.  , 
     0.  , 0.82930945, 0.71799358, 0.8813616 , 0.51874795], 
     [ 0.43353831, 0.00658204, 0.  , 0.  , 0.  , 
     0.10863725, 0.  , 0.  , 0.  , 0.57231074]]) 
관련 문제