Преобразование C разреженной матрицы в python разреженную матрицу - PullRequest
0 голосов
/ 26 марта 2020

У меня ОГРОМНЫЙ файл двоичных данных (8 ГБ), записанный в виде разреженной матрицы (ненулевые данные, индекс строки, индекс col), и я хочу прочитать / импортировать его в C по соображениям скорости. Затем, когда матрица уже построена, я хочу импортировать ее в Python (с интерфейсом ctypes) для удобства отображения. На данный момент мне удалось написать весь код только в python, и он работает. Мне это не нравится, потому что он потребляет много оперативной памяти. Вот почему я хочу сократить проблему в 2.

У кого-нибудь есть идеи о том, как написать разреженную матрицу в C и импортировать ее в разреженном формате python через ctypes?

Заранее спасибо.

Ниже вы найдете мой python -одный код для чтения двоичного файла и импорта данных, чтобы вернуть его в виде разреженной матрицы.

<!-- language: lang-py -->
def Sparse_read(binFileName,DoseGridSize,NbrSpots):
NbrVoxels = DoseGridSize[0]*DoseGridSize[1]*DoseGridSize[2]
sparse2DMatrix = np.array((NbrVoxels,NbrSpots))

try:
    fid = open(binFileName,'rb')
except IOError:
    print('Unable to open file ', binFileName)



col_index = []
row_index = []
beamlet_data = []
last_stacked_col = 0
num_unstacked_col = 1

for i in range(NbrSpots):

    [NonZeroVoxels] = struct.unpack('i', fid.read(4))
    [BeamID] = struct.unpack('i', fid.read(4))
    [LayerID] = struct.unpack('i', fid.read(4))
    [xcoord] = struct.unpack('<f',fid.read(4))
    [ycoord] = struct.unpack('<f', fid.read(4))
    print("Spot " + str(i) + ": BeamID=" + str(BeamID) + " LayerID=" + str(LayerID) + " Position=(" + str(xcoord) + ";" + str(ycoord) + ")")


    ReadVoxels = 0
    while(1):
        [NbrContinuousValues] = struct.unpack('i',fid.read(4))
        ReadVoxels+=NbrContinuousValues

        [FirstIndex] = struct.unpack('i',fid.read(4))

        for j in range(NbrContinuousValues):
            [temp] = struct.unpack('<f',fid.read(4))
            beamlet_data.append(temp)
            row_index.append(FirstIndex+j)


        if (ReadVoxels >= NonZeroVoxels):
            index_list = np.ones((NonZeroVoxels,), dtype=int) * (i-last_stacked_col)
            col_index = col_index + index_list.tolist()

            if i == 0:
                sparse2DMatrix = sp.csc_matrix((beamlet_data, (row_index, col_index)), shape=(NbrVoxels, 1), dtype=np.float32)
                row_index = []
                col_index = []
                beamlet_data = []
                last_stacked_col = i+1
                num_unstacked_col = 1
            elif(len(beamlet_data) > 1e7):
                A = sp.csc_matrix((beamlet_data, (row_index, col_index)), shape=(NbrVoxels, num_unstacked_col),dtype=np.float32)
                sparse2DMatrix = sp.hstack([sparse2DMatrix, A])
                row_index = []
                col_index = []
                beamlet_data = []
                last_stacked_col = i+1
                num_unstacked_col = 1
            else:
                num_unstacked_col += 1

            break

# stack last cols  
A = sp.csc_matrix((beamlet_data, (row_index, col_index)), shape=(NbrVoxels, num_unstacked_col-1), dtype=np.float32)
sparse2DMatrix = sp.hstack([sparse2DMatrix, A])

fid.close()

return sparse2DMatrix
...