将 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 有两个不同的任意长度列表…
我在 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 有两个不同的任意长度列表…