4

对于一些学校作业,我一直试图让 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'
4

1 回答 1

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常量来检测和剥离;

for line in infile:
    if line.startswith(codecs.BOM_UTF8):
        line = line[len(codecs.BOM_UTF8):]
    x, y = line.split()

正如codecs文档所解释的那样:

由于 UTF-8 是 8 位编码,因此不需要 BOM U+FEFF,解码字符串中的任何字符(即使它是第一个字符)都被视为ZERO WIDTH NO-BREAK SPACE.

如果没有外部信息,就不可能可靠地确定使用哪种编码对字符串进行编码。每个charmap编码都可以解码任何随机字节序列。但是,UTF-8 无法做到这一点,因为 UTF-8 字节序列的结构不允许任意字节序列。为了提高检测 UTF-8 编码的可靠性,Microsoft"utf-8-sig"为其记事本程序发明了一种 UTF-8(Python 2.5 调用)的变体:在将任何 Unicode 字符写入文件之前,一个 UTF-8写入编码的 BOM(看起来像这样的字节序列:0xef, 0xbb, )。0xbf因为任何charmap编码文件都不太可能以这些字节值开头(例如映射到

LATIN SMALL LETTER I WITH DIAERESIS
RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
INVERTED QUESTION MARK

utf-8-sig在 iso-8859-1) 中,这增加了可以从字节序列中正确猜出编码的概率。所以这里的 BOM 不是用来确定用于生成字节序列的字节顺序,而是作为帮助猜测编码的签名。在编码时,编utf-8-sig解码器会将0xef,作为前三个字节写入文件。如果它们作为文件中的前三个字节出现,则解码时将跳过这三个字节。在 UTF-8 中,不鼓励使用 BOM,通常应避免使用。0xbb0xbfutf-8-sig

于 2015-01-31T15:00:56.397 回答