Python: ValueError: не удалось преобразовать строку в число с плавающей точкой: '0'
Для некоторых школьных заданий я пытался заставить 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'
1 ответ
В вашем файле данных есть спецификация UTF-8; это то, что мои интерактивные состояния сеанса Python 2 преобразуются в float:
>>> '0'
'\xef\xbb\xbf0'
\xef\xbb\xbf
bytes - это кодированный UTF-8 U + FEFF ZERO WIDTH NO-BREAK SPACE, обычно используемый в качестве знака порядка байтов, особенно в продуктах Microsoft. UTF-8 не имеет проблем с порядком байтов, отметка не требуется для записи порядка байтов, как для UTF-16 или UTF-32; вместо этого Microsoft использует его в качестве помощи для обнаружения кодировок.
На Python 3 вы можете открыть файл, используя utf-8-sig
кодек; этот кодек ожидает спецификацию в начале и удалит ее:
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-битной кодировкой, никакая спецификация не требуется, и любая
U+FEFF
символ в декодированной строке (даже если это первый символ) рассматривается какZERO WIDTH NO-BREAK SPACE
,Без внешней информации невозможно достоверно определить, какая кодировка использовалась для кодирования строки. Каждая кодировка charmap может декодировать любую случайную последовательность байтов. Однако это невозможно с UTF-8, поскольку байтовые последовательности UTF-8 имеют структуру, которая не допускает произвольных байтовых последовательностей. Чтобы повысить надежность, с которой может быть обнаружена кодировка UTF-8, Microsoft изобрела вариант UTF-8 (который Python 2.5 вызывает
"utf-8-sig"
) для своей программы "Блокнот": перед записью в файл любого символа Unicode, кодируется спецификация UTF-8 (которая выглядит следующим образом как последовательность байтов: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
Кодировка может быть правильно угадана из последовательности байтов. Таким образом, здесь спецификация используется не для определения порядка байтов, используемого для генерации последовательности байтов, а в качестве сигнатуры, которая помогает угадывать кодировку. По кодированиюutf-8-sig
кодек напишу0xef
,0xbb
,0xbf
как первые три байта в файл. На декодированиеutf-8-sig
пропустит эти три байта, если они появятся как первые три байта в файле. В UTF-8 использование спецификации не рекомендуется и, как правило, ее следует избегать.