Numpy массивы как-то ломаются при кодировании и записи в файл - PullRequest
0 голосов
/ 02 августа 2020

Я пытаюсь хранить большие массивы numpy внутри файлов. Для этого я сначала генерирую их, затем вызываю array.tobytes() и, наконец, записываю его в файл.

Вот пример кода, который я использую:

import numpy as np

def main():
    val = 9 
    file = open("asdf.jkl", 'wb')
    array_1 = np.full((10, 10), val, dtype = "uint32")
    writelines = []
    print(array_1)

    for i in range(10):
        writelines.append(np.full((16, 16), i, dtype = "uint8"))
        writelines = [array_1.tobytes()] + writelines
    file.write("\n".encode('utf-8').join(writelines))
    file.close()
    
    with open("asdf.jkl", "r") as file:
        lines = file.readlines()
        array_2 = np.fromstring(bytes(lines[0][:-1], "utf-8"), dtype = "uint32").reshape(10,10)
        print(array_2)
main()

The проблема в следующем: если я даю val значение 1-di git, он работает хорошо и делает то, что ожидается. Однако, если я даю val что-нибудь больше 9, он вылетает со следующим сообщением об ошибке:

Traceback (most recent call last):
  File "arrays.py", line 20, in <module>
    main()
  File "arrays.py", line 18, in main
    array_2 = np.fromstring(bytes(lines[0][:-1], "utf-8"), dtype = "uint32").reshape(10, 10)
ValueError: cannot reshape array of size 0 into shape (10,10)

Какого черта он один раз дает ожидаемый результат, а затем перестает работать по прихоти? Почему размер array_2 равен 0? Что я делаю не так?

Помощь будет очень благодарна, поскольку я не мог решить эту проблему в течение последних 2 дней. Спасибо!

1 Ответ

1 голос
/ 03 августа 2020

Проблема в том, что вы храните свои данные с '\n' в качестве разделителя; Это будет работать, только если '\n' нигде не отображается в ваших фактических данных. Символ '\n' - это ASCII (или UTF-8), закодированный как число 10 (см. https://www.asciitable.com/), поэтому, когда вы записываете свой массив, полный 10 s, он эквивалентен выписать кучу '\n' s. Когда вы снова считываете данные и разбиваете их на '\n', он ничего не возвращает (или ничего особенного) перед первым '\n', поэтому он жалуется на попытку изменить форму массива размером 0.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...