Учитывая ваш комментарий, я полагаю, что вы в итоге получили две спецификации.
Давайте рассмотрим небольшой пример. Я использую встроенный open
вместо pd.read_csv
/ pd.to_csv
, но значение параметра encoding
такое же.
Давайте создадим файл, сохраненный как UTF-8 с Спецификация:
>>> text = 'foo'
>>> with open('/tmp/foo', 'w', encoding='utf-8-sig') as f:
... f.write(text)
Теперь давайте прочитаем это обратно. Но мы используем другую кодировку: «utf-8» вместо «utf-8-sig». В вашем случае вы вообще не указали параметр кодирования, но значением по умолчанию, скорее всего, является «utf-8» или «cp-1252», которые оба хранят спецификацию. Таким образом, следующее более или менее эквивалентно вашему фрагменту кода:
>>> with open('/tmp/foo', 'r', encoding='utf8') as f:
... text = f.read()
...
>>> text
'\ufefffoo'
>>> with open('/tmp/foo_converted', 'w', encoding='utf-8-sig') as f:
... f.write(text)
Спецификация читается как часть текста; это первый символ (здесь представлен как "\ufeff"
).
Давайте посмотрим, что на самом деле находится в файлах, используя подходящий инструмент командной строки:
$ hexdump -C /tmp/foo
00000000 ef bb bf 66 6f 6f |...foo|
00000006
$ hexdump -C /tmp/foo_converted
00000000 ef bb bf ef bb bf 66 6f 6f |......foo|
00000009
В UTF-8, Спецификация кодируется как три байта EF BB BF
. Очевидно, что второй файл имеет два из них. Таким образом, даже программа, поддерживающая спецификацию, найдет какой-то бессмысленный символ в начале foo_converted , поскольку спецификация удаляется только один раз.