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 использование спецификации не рекомендуется и, как правило, ее следует избегать.

Другие вопросы по тегам