Замена struct.unpack на numpy.ndarray для ускорения чтения огромных двоичных файлов - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть огромный двоичный файл (4Go), в котором существует несколько (1000,95) -матриц. Предположим, что есть 3 матрицы, они хранятся следующим образом: первая строка матрицы 1, первая строка матрицы 2, первая строка матрицы 3, затем вторая строка матрицы 1, вторая строка матрицы 2, вторая строка матрицы 3,затем третья строка матрицы 1, ... Чтобы прочитать их, я использовал двойной цикл struct.unpack ().

Вот упрощенный фрагмент моего кода для чтения одной матрицы:

import numpy as np
import struct

file = r'C:\...\binaryfile'

startReadingFrom = 1406853
nextRowOfTheMatrix = 3480788

def old():
    with open(file, 'rb') as f:
        f.seek(startReadingFrom, 0)

        nodeValues = np.empty((1000, 95))
        for i in range(1000):
            for j in range(95):
                buffer = f.read(8)
                res = struct.unpack('>d', buffer)[0]
                nodeValues[i, j] = res
            f.seek(nextRowOfTheMatrix, 1)
    return nodeValues

Проблема в том, что мой код работает слишком медленно. Я хочу улучшить производительность, заменив struct.unpack () на numpy.ndarray, как я обнаружил в Ускорение python в struct.unpack . Это моя новая функция:

def new():
    with open(file, 'rb') as f:
        f.seek(startReadingFrom, 0)

        nodeValues = np.empty((1000, 95))
        for i in range(1000):
            buffer = f.read(8 * 95)
            res = np.ndarray((1, 95), '>d', buffer)[0]
            nodeValues[i,:] = res
            f.seek(nextRowOfTheMatrix, 1)

    return nodeValues

Это уже улучшило производительность функции, как показано ниже

%timeit old()
#109 ms ± 6.98 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit new()
#58.9 ms ± 3.59 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Моя проблема в том, что я хочу сделать это только в одном np.ndarray((1000,95),... что может улучшить скорость. Но так как файл огромен, я не могу найти, как передать буфер в функцию np.ndarry, не прочитав весь файл (f.read ()). Может ли кто-нибудь помочь мне улучшить мою функцию? Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...