У меня есть двоичный файл, состоящий из заголовка, а затем список записей.Каждая запись представляет собой список из n целых чисел без знака, за которым следует список n целых чисел со знаком. n отличается для каждой записи.Целые числа без знака являются значениями для переменной x , а целые числа со знаком являются значениями для переменной y .Например, данные могут выглядеть так:
4 3 1 5 -10 50 40 30
4 5 6 30 -25 100
5 4 30 55
6 4 6 7 4 -20 30 30 -50 60
Мне нужно прочитать этот файл и сохранить каждую запись в массиве ( n , 2), где первый столбец содержит x значений, а второй столбец содержит значения y .Затем я хочу сохранить все массивы в массив контейнеров.В итоге у меня должно получиться что-то вроде
np.array([
np.array([[4, -10], [3, 50], [1, 40], [5, 30]]),
np.array([[4, 30], [5, -25], [6, 100]]),
np.array([[5, 30], [4, 55]]),
array([], shape=(0, 2)),
np.array([[6, -20], [4, 30], [6, 30], [7, -50], [4, 60]])
])
. Бинарный файл занимает около 200 МБ и содержит около 10 миллионов записей.Длина каждой записи указана в данных заголовка, а у меня - в массиве lengths
.Обратите внимание, что некоторые записи могут быть пустыми, обозначенные длиной 0.
. Сейчас у меня есть рабочее решение, использующее struct.unpack , но оно действительно медленное (чтение файла занимаетпара минут).Я перебираю массив lengths
и запускаю функцию read_single_record
.
def read_single_record(f, length, x_fmt, y_fmt):
"""x_fmt and y_fmt are tuples of
(struct format character, size in bytes).
"""
raw = f.read(length)
n_vals = length // (x_fmt[1] + y_fmt[1])
val = struct.unpack(
f'{n_vals}' + x_fmt[0] + f'{n_vals}' + y_fmt[0], raw)
val = np.array(val, dtype=np.int16).reshape((n_vals, 2), order='F')
# do some more data processing
# ...
return val
records = np.empty(nb_records, dtype='object')
for i, length in enumerate(lengths):
records[i] = read_single_record(f, length, x_fmt, y_fmt)
Я видел другие предложить , используя np.fromfile , но я не совсем уверен, как использовать его с записями переменной длины.
Какой самый эффективный способ чтения записей переменной длины из моего двоичного файла?