Как правильно сохранить и загрузить данные numpy.array()?

Интересно, как правильно сохранять и загружать данные numpy.array. В настоящее время я использую метод numpy.savetxt(). Например, если я получил массив markers, который выглядит следующим образом:

enter image description here

Я пытаюсь сохранить его с помощью:

numpy.savetxt('markers.txt', markers)

В другом script я пытаюсь открыть ранее сохраненный файл:

markers = np.fromfile("markers.txt")

И что я получаю...

enter image description here

Сохраненные данные сначала выглядят следующим образом:

0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00

Но когда я сохраняю только загруженные данные с использованием того же метода, т.е. numpy.savetxt() выглядит следующим образом:

1.398043286095131769e-76
1.398043286095288860e-76
1.396426376485745879e-76
1.398043286055061908e-76
1.398043286095288860e-76
1.182950697433698368e-76
1.398043275797188953e-76
1.398043286095288860e-76
1.210894289234927752e-99
1.398040649781712473e-76

Что я делаю неправильно? PS Нет никакой другой операции "за кулисами", которую я выполняю. Просто сохраняйте и загружайте, и что я получаю. Заранее благодарю вас.

Ответ 1

Самый надежный способ, который я нашел для этого, - использовать np.savetxt с np.loadtxt, а не np.fromfile, который лучше подходит для двоичных файлов, написанных с помощью tofile. Методы np.fromfile и np.tofile записывают и читают двоичные файлы, тогда как np.savetxt записывает текстовый файл. Итак, например:

In [1]: a = np.array([1, 2, 3, 4])
In [2]: np.savetxt('test1.txt', a, fmt='%d')
In [3]: b = np.loadtxt('test1.txt', dtype=int)
In [4]: a == b
Out[4]: array([ True,  True,  True,  True], dtype=bool)

Или:

In [5]: a.tofile('test2.dat')
In [6]: c = np.fromfile('test2.dat', dtype=int)
In [7]: c == a
Out[7]: array([ True,  True,  True,  True], dtype=bool)

Я использую прежний метод, даже если он медленнее, и создает большие файлы (иногда): двоичный формат может быть зависимым от платформы (например, формат файла зависит от контентоспособности вашей системы).

Существует независимый от платформы формат для массивов NumPy, который можно сохранить и прочитать с помощью np.save и np.load:

In  [8]: np.save('test3.npy', a)    # .npy extension is added if not given
In  [9]: d = np.load('test3.npy')
In [10]: a == d
Out[10]: array([ True,  True,  True,  True], dtype=bool)

Ответ 2

np.fromfile() имеет аргумент ключевого слова sep=:

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

Значение по умолчанию sep="" означает, что np.fromfile() пытается читать его как двоичный файл, а не текстовый файл, разделенный пробелом, поэтому вы возвращаете ненужные значения. Если вы используете np.fromfile('markers.txt', sep=" "), вы получите результат, который вы ищете.

Однако, как отмечали другие, np.loadtxt() является предпочтительным способом преобразования текстовых файлов в массивы numpy, и если файл не нужен чтобы быть читаемым человеком, обычно лучше использовать бинарные форматы (например, np.load()/np.save()).