Лучший способ хранить большое количество чисел в файле с Python? - PullRequest
1 голос
/ 10 февраля 2020

У меня есть программа, которая генерирует очень большую последовательность чисел с плавающей запятой, обычно около десятков миллионов. Мне нужен хороший способ хранить их в файле. Я буду писать их по порядку и читать их, используя Python. Число с плавающей точкой находится в одномерном массиве, подобном следующему:

[39534.543, 834759435.3445643, 1.003024032, 0.032543, 434.0208...]

(Эти числа являются примерами, и я просто разбиваю их по клавишам).

Код для генерации чисел:

for x in range(16384):
    for y in range(16384):
        float = <equation with x and y>
        <write float to file>

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

Вы можете хранить числа с плавающей запятой в виде 64-битных двойных чисел, используя функцию struct.pack:

from struct import pack, unpack

array = [39534.543, 834759435.3445643, 1.003024032, 0.032543, 434.0208]

with open('store', 'wb') as file:
    file.write(pack('d' * len(array) , *array))

, чтобы впоследствии вы могли получить значения массива, используя struct.unpack:

with open('store', 'rb') as file:
    packed = file.read()
    array = unpack('d' * (len(packed) // 8), packed) # 8 bytes per double
0 голосов
/ 11 февраля 2020

Некоторые из ваших чисел выглядят слишком короткими, чтобы быть случайными. Таким образом, вы можете хранить их в меньше , чем 8 байт с плавающей запятой при сжатии. Например:

Магазин:

import lzma

array = [39534.543, 834759435.3445643, 1.003024032, 0.032543, 434.0208]

with open('store', 'wb') as file:
    file.write(lzma.compress(repr(array).encode()))

Загрузка:

import lzma, ast

with open('store', 'rb') as file:
    array = ast.literal_eval(lzma.decompress(file.read()).decode())

print(array)

Даже со случайными данными я получаю в среднем менее 8 байт:

>>> n = 10**5
>>> a = [random.random() for _ in range(n)]
>>> len(lzma.compress(repr(a).encode())) / n
7.98948

По общему признанию это довольно медленно, по крайней мере с моими случайными данными. Может быть быстрее для неслучайных данных. Или, может быть, попробуйте более низкий уровень сжатия или одно из других сжатий. Модуль pickle также упоминает сжатие, так что, возможно, стоит попробовать.

...