Создайте новый список в CSV, не используя pandas: return UnicodeDecodeError - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь создать новый список в моем существующем CSV-файле (не используя панд).Вот мой код:

with open ('/Users/Weindependent/Desktop/dataset/albumlist.csv','r') as case0:
    reader = csv.DictReader(case0)
    album = []
    for row in reader:
        album.append(row)
print ("Number of albums is:",len(album))

Файл CSV был загружен из набора данных *5004* Top 500 альбомов Rolling Stone на data.world .

Моя логика заключается в созданиипустой список с именем альбома и все записи в этом списке.Но похоже, что в строке for row in reader есть какая-то проблема.

полученное сообщение об ошибке:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xca in position 1040: invalid continuation byte

Может кто-нибудь сообщить мне, что я сделал не так?

1 Ответ

0 голосов
/ 11 февраля 2019

Вам необходимо открыть файл в правильном кодеке;UTF-8 не правильный.Набор данных не указывает его, но я определил, что наиболее вероятным кодеком является mac_roman:

with open ('/Users/Weindependent/Desktop/dataset/albumlist.csv', 'r', encoding='mac_roman') as case0:

Оригинальный набор данных Kaggle не документирует его, иразличные ядра, которые используют набор, просто затуманивают кодировку.Это явно 8-битный латинский вариант (большинство данных - ASCII с несколькими отдельными 8-битными кодовыми точками).

Итак, я проанализировал данные и обнаружил, что в 9 строках есть только две такие кодовые точки.:

>>> import re
>>> eightbit = re.compile(rb'[\x80-\xff]')
>>> with open('albumlist.csv', 'rb') as bindata:
...     nonascii = [l for l in bindata if eightbit.search(l)]
...
>>> len(nonascii)
9
>>> {c for l in nonascii for c in eightbit.findall(l)}
{b'\x89', b'\xca'}

Байт 0x89 появляется только в одной строке:

>>> sum(l.count(b'\x89') for l in nonascii)
1
>>> sum(l.count(b'\xca') for l in nonascii)
22
>>> next(l for l in nonascii if b'\x89' in l)
b'359,1972,Honky Ch\x89teau,Elton John,Rock,"Pop Rock,\xcaClassic Rock"\r\n'

Это ясно Элтон Джон 1972 Honky Château альбом , поэтому0x89 байт должен представлять U + 00E2 LATIN МАЛЕНЬКОЕ ПИСЬМО A С CIRCUMFLEX codepoint.

Все байты 0xCA представляют альтернативный пробел, все они отображаются справа после запятых в жанреи поджанровые столбцы (за исключением одного альбома):

>>> import csv
>>> for row in csv.reader((l.decode('ascii', 'backslashreplace') for l in nonascii)):
...     for col in row:
...         if '\\' in col: print(col)
...
Reggae,\xcaPop,\xcaFolk, World, & Country,\xcaStage & Screen
Reggae,\xcaRoots Reggae,\xcaRocksteady,\xcaContemporary,\xcaSoundtrack
Electronic,\xcaStage & Screen
Soundtrack,\xcaDisco
Rock,\xcaBlues
Blues Rock,\xcaElectric Blues,\xcaHarmonica Blues
Garage Rock,\xcaPsychedelic Rock
Honky Ch\x89teau
Pop Rock,\xcaClassic Rock
Funk / Soul,\xcaFolk, World, & Country
Rock,\xcaPop
Stan Getz\xca/\xcaJoao Gilberto\xcafeaturing\xcaAntonio Carlos Jobim
Bossa Nova,\xcaLatin Jazz
Lo-Fi,\xcaIndie Rock

Эти байты 0xCA почти наверняка представляют собой кодовую точку U + 00A0 NO-BREAK SPACE .

С этимидва сопоставления, вы можете попытаться определить, какие 8-разрядные кодеки будут выполнять одно и то же сопоставление.Вместо того, чтобы вручную опробовать все кодеки Python Я использовал 8-битное отображение кодеков Tripleee , чтобы увидеть, какие кодеки используют эти отображения.Всего их два:

  • 0x89

â (U + 00E2): mac_arabic, mac_croatian, mac_farsi, mac_greek, mac_iceland, mac_roman, mac_romanian, mac_turkish

  • 0xca

    (U + 00A0): mac_centeuro, mac_croatian, mac_cyrillic, mac_greek, mac_iceland, mac_latin2, mac_roman, mac_romanian, mac_turkish

В обоих наборах перечислены 6 кодировок:

>>> set1 = set('mac_arabic, mac_croatian, mac_farsi, mac_greek, mac_iceland, mac_roman, mac_romanian, mac_turkish'.split(', '))
>>> set2 = set('mac_centeuro, mac_croatian, mac_cyrillic, mac_greek, mac_iceland, mac_latin2, mac_roman, mac_romanian, mac_turkish'.split(', '))
>>> set1 & set2
{'mac_turkish', 'mac_iceland', 'mac_romanian', 'mac_greek', 'mac_croatian', 'mac_roman'}

Из них Mac OS Roman mac_roman кодек, вероятно, наиболее вероятноиспользовались в качестве Microsoft Excel для Mac , использовались Mac Roman для создания CSV-файлов в течение длительного времени.Тем не менее, это не имеет значения, любой из этих 6 будет работать здесь.

Вы можете заменить эти неразрывные пробелы U + 00A0, если вы хотите разделить столбцы жанра и поджанра (на самом делестолбцы жанра и style , если они взяты из Discogs).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...