将 csv 持久化的浮点数列表读回浮点数列表

Reading a csv persisted list of floats back into a list of floats

我在 csv 文件中保留了一个浮点数列表,因此它显示为(单行)。

"[6.61501123e-04 1.23390303e-04 1.59454121e-03 2.17852772e-02
  :
 3.02987776e-04 3.83064064e-03 6.90607396e-04 3.30468375e-03
 2.78064613e-02]"

现在,当将阅读转换回列表时,我使用 ast literal_eval 方法: probs = [float(p) for p in ast.literal_eval(row['prob_array'])]

我得到这个错误:

    probs = [float(p) for p in ast.literal_eval(row['prob_array'])]
  File "/Users/santino/anaconda/lib/python2.7/ast.py", line 49, in literal_eval
    node_or_string = parse(node_or_string, mode='eval')
  File "/Users/santino/anaconda/lib/python2.7/ast.py", line 37, in parse
    return compile(source, filename, mode, PyCF_ONLY_AST)
  File "<unknown>", line 1
    [6.61501123e-04 1.23390303e-04 1.59454121e-03 2.17852772e-02
                                 ^
SyntaxError: invalid syntax

不确定如何指示 ast 读取指数语法,或者我是否错误地假设是指数语法导致了异常。

编辑:我使用 csv.DictWriter 保存到 csv 文件中。有什么不同的方法可以坚持吗?

编辑 2:

with open("./input_file.csv","w") as r:
    writer = csv.DictWriter(r,fieldnames=["item_id","item_name","prob_array"])
    writer.writeheader()
        res_list = ...
        for i,res in enumerate(res_list):
            row_dict = {}
            row_dict['item_id'] = id_list[i]
            row_dict['prob_array'] = res
            row_dict['item_name'] = item_list[i]
            writer.writerow(row_dict)

CSV 仅存储字符串列。用它来存储字符串、整数、浮点数和其他一些基本类型是可以的,只要您手动转换对象:无论何时将 str(i) 转换为整数,都可以使用 [=14 取回整数=].

但对于浮动列表而言,情况并非如此。没有函数可以用来在任意列表上取回 str(lst) 的结果。1 而且它不适合......无论你有什么,这似乎是最可能是一个 numpy 数组或 Pandas 系列......要么。2

如果您可以将每个浮点数存储为单独的列,而不是将它们的列表存储在单个列中,这是最简单的答案。但不一定合适。3

因此,您只需要选择一些其他函数来代替隐式 str可以 通过简单的函数调用将其反转。有一些格式专为将数据持久化为字符串而设计——JSON、XML,甚至是嵌套的 CSV——所以这是第一个要看的地方。


通常第一个看到的应该是JSON。只要它可以处理您的所有数据(这里肯定可以),它的使用非常简单,有人已经想到抛出所有烦人的边缘情况,并且有代码可以为宇宙中的每个平台解析它。

所以,你这样写值:

row_dict['prob_array'] = json.dumps(res)

然后你可以这样读回来:

prob_array = json.loads(row['prob_array'])

如果 prob_array 实际上是一个 numpy 数组或 Pandas 系列或其他东西而不是列表,您需要通过 list 进行转换,或者使用 numpy 或 Pandas JSON 方法而不是 stdlib 模块。

这里唯一真正的问题是,如果您希望 CSV 为 human-readable/editable,转义的逗号和引号可能会非常难看。


在这种情况下,您可以定义一种更简单的格式,该格式仍然易于为您的特定数据编写和解析,并且更易于阅读,例如 space 分隔的浮点数:

row_dict['prob_array'] = ' '.join(map(str, res))

prob_array = [float(val) for val in row['prob_array'].split()]

1.有时您可以使用 ast.literal_eval,但依赖它绝不是一个好主意,它在这里不起作用。

2。 numpy 和 Pandas 使用的人类可读格式甚至比 Python 列表使用的格式对解析器更不友好。你可以切换到他们的repr而不是他们的str,但它仍然不会ast.literal_eval

3。举一个明显的例子,想象一个 table 有两个不同的任意长度列表…