对于一些学校作业,我一直试图让pyplot根据Logger Pro的数据为我绘制一些科学图表。我遇到了错误
ValueError: could not convert string to float: '0'
这是该计划:
plot.py
-------------------------------
import matplotlib.pyplot as plt
import numpy as np
infile = open('text', 'r')
xs = []
ys = []
for line in infile:
print (type(line))
x, y = line.split()
# print (x, y)
# print (type(line), type(x), type(y))
xs.append(float(x))
ys.append(float(y))
xs.sort()
ys.sort()
plt.plot(xs, ys, 'bo')
plt.grid(True)
# print (xs, ys)
plt.show()
infile.close()
输入文件包含:
text
-------------------------------
0 1.33
1 1.37
2 1.43
3 1.51
4 1.59
5 1.67
6 1.77
7 1.86
8 1.98
9 2.1
这是我在运行程序时收到的错误消息:
Traceback (most recent call last):
File "\route\to\the\file\plot01.py", line 36, in <module>
xs.append(float(x))
ValueError: could not convert string to float: '0'
答案 0 :(得分:5)
您的数据文件中有UTF-8 BOM表;这就是我的Python 2交互式会话状态被转换为浮点数:
>>> '0'
'\xef\xbb\xbf0'
\xef\xbb\xbf
字节是UTF-8编码的U+FEFF ZERO WIDTH NO-BREAK SPACE,通常用作字节顺序标记,尤其是Microsoft产品。 UTF-8没有字节顺序问题,记录字节顺序所需的标记就像UTF-16或UTF-32一样;相反,Microsoft使用它来帮助检测编码。
在Python 3上,您可以使用utf-8-sig
编解码器打开文件;此编解码器在开始时期望BOM并将其删除:
infile = open('text', 'r', encoding='utf-8-sig')
在Python 2上,您可以使用codecs.BOM_UTF8
constant来检测和去除;
for line in infile:
if line.startswith(codecs.BOM_UTF8):
line = line[len(codecs.BOM_UTF8):]
x, y = line.split()
作为codecs
documentation explains it:
由于UTF-8是8位编码,因此不需要BOM,解码后的字符串中的任何
U+FEFF
字符(即使它是第一个字符)都被视为ZERO WIDTH NO-BREAK SPACE
。如果没有外部信息,就无法可靠地确定使用哪种编码来编码字符串。每个charmap编码可以解码任何随机字节序列。然而,UTF-8无法实现这一点,因为UTF-8字节序列的结构不允许任意字节序列。为了提高可以检测到UTF-8编码的可靠性,Microsoft为其Notepad程序发明了UTF-8的变体(Python 2.5调用
)是不太可能的。"utf-8-sig"
):在将任何Unicode字符写入文件之前,写入UTF-8编码的BOM(看起来像字节序列:0xef
,0xbb
,0xbf
)。因为任何charmap编码文件都以这些字节值开头(例如映射到LATIN SMALL LETTER I WITH DIAERESIS RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK INVERTED QUESTION MARK
在iso-8859-1中),这增加了从字节序列正确猜出
utf-8-sig
编码的可能性。因此,BOM不用于确定用于生成字节序列的字节顺序,而是用作有助于猜测编码的签名。在编码时,utf-8-sig
编解码器会将0xef
,0xbb
,0xbf
写为文件的前三个字节。在解码utf-8-sig
时,如果它们显示为文件中的前三个字节,则将跳过这三个字节。在UTF-8中,不鼓励使用BOM,一般应避免使用。