使用eval()创建numpy.float64

时间:2012-02-28 02:57:28

标签: python types numpy eval

我环顾四周,并没有找到任何使用内置eval函数创建numpy.float64的信息。

我想要的是:

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'>

你们有什么建议吗?我错过了一个明显的方法吗?


修改

我将在data_str中处理的数字的精确度不会超过15-16位数。 因此,将字符串转换为floatnumpy.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'>

我认为通过在eval全局变量中定义“{_builtins__”到None会避免加载float的默认定义,我在本地人中重新定义......似乎不可能eval命名空间中取出(或替换此内容)内置类型(如floatint ...)。对此有任何启示都是受欢迎的:)

2 个答案:

答案 0 :(得分:2)

您的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'>

答案 1 :(得分:2)

你可以做的是复制ast.literal_eval()所做的事情,但不是只执行AST,而是先调用numpy.float64构造函数。