Чтение txt-файла как dict, содержащего numpy-массив - PullRequest
0 голосов
/ 14 сентября 2018

У меня много файлов .txt, которые я хочу прочитать. Файлы .txt были сохранены путем преобразования словаря python в строку и сохранения строки в файле .txt.

param_string = str(parameters-as-dict)
text_file = open(parameter_file_path, "w")
text_file.write(param_string)
text_file.close()

Записи в dict имеют смешанные типы (float, int, string, ...). В некоторых файлах одна запись в dict является массивом numpy и сохраняется в txt-файле как

'epsilons': array([...])

Поскольку я хочу получить доступ к значениям, сохраненным в dict, по их именам, я теперь хочу прочитать txt-файл и снова загрузить их как dict. Это легко работает с

f = open(path, 'r')
parameters = ast.literal_eval(f.read())

, пока в файле нет пустого массива. Когда присутствует numpy-массив, я получаю ошибку:

Файл "... / python3.6 / ast.py", строка 84, в _convert поднять ValueError ('неправильный узел или строка:' + repr (node)) ValueError: неправильный узел или строка: <_ast.Call объект в 0x7fb5428cc630>

Что имеет смысл, глядя на документацию as.literal_eval (https://docs.python.org/2/library/ast.html), в которой написано

Безопасное вычисление узла выражения или кодировки Unicode или Latin-1 строка, содержащая литерал Python или отображение контейнера. Строка или предоставленный узел может состоять только из следующего литерала Python структуры: строки, числа, кортежи, списки, слова, логические значения и None.

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

РЕДАКТИРОВАТЬ: проблема не только в массиве numpy, но и когда я сохранил объект, например. определенный класс:

 , 'foo' : <class bar>,

Решение, в котором все, что не может быть проанализировано как некоторый тип числа / bool / некоторый тип данных knonw, автоматически сохраняется в виде строки, так же, как оно удовлетворяет моим потребностям.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

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

parameters = {}    
with open("file.txt") as f:
    for line in f:
        (key, val) = line.split(':')
        if val[:6] == '<class'
            # string representation like '<class bar>'
            # ast.literal_eval() can't handle this, and neither can eval()
            # this is just a string literal, so keep it as such:
            parameters[key] = val  
            continue
        try:
            parameters[key] = ast.literal_eval(val)
        except ValueError as e:
            # for unsupported data structures like np.array
            parameters[key] = eval(val)
0 голосов
/ 14 сентября 2018

Полагаю, вам придется проверять массив за строкой.Быстрое и грязное предложение:

parameters = {}    
with open("file.txt") as f:
    for line in f:
       (key, val) = line.split(':')
       if 'array' in val:
           s = val.split('(', 1)[1].split(')')[0]
           parameters[key] = np.array(ast.literal_eval(s))
       else:
           parameters[key] = ast.literal_eval(val)

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

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