我正在尝试在现有的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文件是从Rolling Stone's Top 500 albums data set on data.world下载的。
我的逻辑是创建一个名为专辑的空列表,并将所有记录包含在该列表中。但是看来for row in reader
这行有问题。
我收到的错误消息是:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xca in position 1040: invalid continuation byte
谁能让我知道我做错了什么?
答案 0 :(得分:1)
您需要使用正确的编解码器打开文件; UTF-8不是正确的。数据集未指定它,但我确定最可能的编解码器是mac_roman
:
with open ('/Users/Weindependent/Desktop/dataset/albumlist.csv', 'r', encoding='mac_roman') as case0:
original Kaggle dataset无需费心去记录它,并且使用该集合的各种内核都只是破坏编码。显然,它是一个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'
这显然是Elton John's 1972 Honky Château album,因此0x89字节必须代表U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX代码点。
所有0xCA字节似乎都代表一个替代的空格字符,它们都在genre和subgenre列中的逗号后出现(在一个专辑中除外):
>>> 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位编解码器将进行相同的映射。我不是手动尝试all Python's codecs,而是使用Tripleee's 8-bit codec mapping来查看哪些编解码器使用了这些映射。只有两个:
- 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
编解码器很可能很长时间以来一直被用作Mac used Mac Roman to create CSV files的Microsoft Excel。但是,这并不重要,这6个都可以在这里工作。
如果要拆分流派和子流派列,则可能要替换那些U + 00A0不间断空格(如果流派和 style 列取自Discogs,则应为真正的流派)。 / p>