У меня есть огромный двоичный файл (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 ()). Может ли кто-нибудь помочь мне улучшить мою функцию? Заранее спасибо.