Создание numpy.float64 с использованием eval () - PullRequest
3 голосов
/ 28 февраля 2012

Я осмотрелся и не нашел никакой информации для создания numpy.float64 с помощью встроенной функции eval.

То, что я хотел бы получить от чего-то вроде:

In [1]: x = eval("1.0")
In [2]: type(x)
Out[2]: <type 'float'>

до:

In [1]: x = eval("1.0")
In [2]: type(x)
Out[2]: <type 'numpy.float64'>

Реальная проблема немного хуже, чем в простом примере, приведенном выше, потому что аргумент, передаваемый eval, чаще всего представляет собой словарь с множеством ключей и значений. Так что было бы невозможно использовать что-то вроде: numpy.float64("1.0").

Чтобы дать вам конкретные реальные данные, с которыми я работаю, вот как может выглядеть строка (она читается из файла):

data_str = '{"var_x": {"value": 1.23, "error": 0.25, "unit": "unit name"},
            "var_y": {"value": 1e+4, "error": 1.3e1, "log": False},
            "var_z": ["a", {"x":1, "y":2}, (1, 2, 3), None]'
data = eval(data_str)

И тогда я бы хотел type(data["var_x"]["value"]) возврат <type 'numpy.float64'>

У вас, ребята, есть предложения? Я пропустил очевидный метод?


EDIT

Точность чисел, с которыми я буду иметь дело в data_str, будет не более 15-16 цифр. Поэтому преобразование строки в float или numpy.float64 не имеет большого значения только для этой цели. Однако эти значения будут переданы в некоторые сложные функции, умножены, разделены ... поэтому, чтобы избежать распространения ошибок, я должен работать с numpy.float64. Одним из обходных путей может быть преобразование (после eval) любого float в numpy.float64, но было бы неплохо иметь прямую интерпретацию с использованием eval.

РЕДАКТИРОВАТЬ # 2

Мне интересно, почему это не работает:

In [1]: import numpy as np
In [2]: x = eval("1.4", {"__builtins__":None, "np":np}, {"float":np.float64})
In [3]: type(x)
Out[3]: <type 'float'>

Я подумал, что определение "__builtins__" для None в глобальных переменных eval позволит избежать загрузки определения по умолчанию для float, которое я переопределяю внутри локальных ... Кажется, невозможно для убрать (или заменить для этого) встроенные типы из пространства имен eval (например, float, int ...). Любой свет на это можно только приветствовать:)

Ответы [ 2 ]

2 голосов
/ 28 февраля 2012

То, что вы могли бы сделать, это скопировать то, что делает ast.literal_eval(), но вместо того, чтобы просто выполнить AST, вы могли бы сначала вводить вызовы конструктору numpy.float64.

2 голосов
/ 28 февраля 2012

Ваш data_str очень похож на действительный JSON.В частности, если бы False были строчными, то это был бы JSON.

Возможно, небезопасно слепо заменять все False на false.Но если это так, то вы можете использовать json.loads и очень удобный хук parse_float для преобразования всех чисел с плавающей точкой в ​​np.float64 s:

import json
import numpy as np
import re

def parse_float(x):
    return np.float64(x)

def lower(match):
    return match.group(1).lower()

data_str = '''{"var_x": {"value": 1.23, "error": 0.25, "unit": "unit name"},
            "var_y": {"value": 1e+4, "error": 1.3e1, "log": False}}'''

data_str = re.sub(r'(False|True)', lower, data_str)
data = json.loads(data_str, parse_float = parse_float)
print(type(data['var_x']['value']))
# <type 'numpy.float64'>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...