Запись необработанных чисел на диск

Мне пришло в голову, что я понятия не имею, как записывать необработанные числовые значения на диск. Как бы я сделал это на Python или C++?!

Я запускаю некоторые симуляции и записываю промежуточные результаты на диск, чтобы он не начинался с нуля в случае сбоя. К сожалению, эти значения занимают гигабайты за гигабайтами места на моем жестком диске.

Будет ли запись числовых значений на диск в виде чисел с плавающей запятой занимать значительно меньше места на диске или есть какие-то другие накладные расходы, которые я не рассматриваю?


person calben    schedule 30.08.2014    source источник
comment
Как вы пишете на диск?   -  person Chip    schedule 30.08.2014
comment
Сколько значащих цифр записывается на диск? Как часто (например, раз в секунду, раз в минуту, так быстро, как может выполняться цикл,...)?   -  person CPlusPlus OOA and D    schedule 31.08.2014
comment
Обычно пишут полный номер и пишут так быстро, как только можно написать. Изначально писал с помощью write csv или через обычный Python IO.   -  person calben    schedule 31.08.2014


Ответы (4)


Наиболее универсальным и мощным вариантом является использование формата HDF5 с помощью интерфейс Python. С сайта:

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

Он также имеет C++ API.

Формат HDF5 широко используется в научном вычислительном сообществе и читается/записывается многими программами. С данными в формате HDF5 можно быстро работать с помощью параллельных утилит.

person damienfrancois    schedule 30.08.2014
comment
это решение, которое я буду использовать, так как это такое полное решение, которое я пропустил. спасибо! - person calben; 31.08.2014

Вы можете свернуть свой собственный двоичный формат и использовать его, но это, вероятно, плохая идея.

Если вы используете Python для работы с числовыми данными, вы почти наверняка используете numpy. Если вы не используете numpy, попробуйте использовать numpy, это здорово.

Получив данные в массиве numpy, вы можете просто использовать их save метод.

person Patrick Collins    schedule 30.08.2014
comment
как я раньше не видел простой маленькой функции сохранения?! это выглядит здорово! - person calben; 31.08.2014

Общий метод в Python заключается в использовании модуля struct.

import struct
print struct.pack("!d", 3.14159)

(Вы можете выбрать, какой порядок байтов использовать. Я использую !, чтобы указать сетевой порядок байтов для переносимости, или не использовать индикатор, чтобы использовать собственный порядок байтов. На самом деле, я не уверен, что IEEE 754 определяет порядок байтов, поэтому я не уверен, что порекомендовать. Возможно, лучше использовать значение по умолчанию.)

person chepner    schedule 30.08.2014

Перед оптимизацией убедитесь, что вы делаете хотя бы что-то подобное (сохраняете числовой тип в его двоичном представлении на диске). Если вы находитесь на этом этапе, а размеры файлов все еще слишком велики, вы можете рассмотреть различные типы сжатых форматов.

#include <iostream>
#include <fstream>

typedef int32_t my_numeric_type;

int main()
{
    using namespace std;

    {
        ofstream output_file("numbers.dat", ios::binary);
        if( !output_file )
        {
            cout << "Failed to open file for writing" << endl;
            return 1;
        }

        for( my_numeric_type i = 0 ; i <= 1000; ++i )
            output_file.write(reinterpret_cast<const char*>(&i), sizeof(i));
    }

    {
        ifstream input_file("numbers.dat", ios::binary);
        if( !input_file )
        {
            cout << "Failed to open file for reading" << endl;
            return 1;
        }

        my_numeric_type i;
        while( input_file.read(reinterpret_cast<char*>(&i), sizeof(i)) )
            cout << i << endl;
    }

    return 0;
}
person CustomCalc    schedule 30.08.2014