Python ile Pandalar'da CSV dosyasını okurken UnicodeDecodeError


411

30.000 benzer dosyayı işleyen bir program çalıştırıyorum. Rastgele sayıda kişi bu hatayı durduruyor ve üretiyor ...

   File "C:\Importer\src\dfman\importer.py", line 26, in import_chr
     data = pd.read_csv(filepath, names=fields)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 400, in parser_f
     return _read(filepath_or_buffer, kwds)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 205, in _read
     return parser.read()
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 608, in read
     ret = self._engine.read(nrows)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 1028, in read
     data = self._reader.read(nrows)
   File "parser.pyx", line 706, in pandas.parser.TextReader.read (pandas\parser.c:6745)
   File "parser.pyx", line 728, in pandas.parser.TextReader._read_low_memory (pandas\parser.c:6964)
   File "parser.pyx", line 804, in pandas.parser.TextReader._read_rows (pandas\parser.c:7780)
   File "parser.pyx", line 890, in pandas.parser.TextReader._convert_column_data (pandas\parser.c:8793)
   File "parser.pyx", line 950, in pandas.parser.TextReader._convert_tokens (pandas\parser.c:9484)
   File "parser.pyx", line 1026, in pandas.parser.TextReader._convert_with_dtype (pandas\parser.c:10642)
   File "parser.pyx", line 1046, in pandas.parser.TextReader._string_convert (pandas\parser.c:10853)
   File "parser.pyx", line 1278, in pandas.parser._string_box_utf8 (pandas\parser.c:15657)
 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xda in position 6: invalid    continuation byte

Bu dosyaların kaynağı / oluşturulması aynı yerden gelir. İçe aktarma işlemine devam etmek için bunu düzeltmenin en iyi yolu nedir?

Yanıtlar:


823

read_csvencodingfarklı biçimlerdeki dosyalarla ilgilenmek için bir seçenek alır . Çoğunlukla read_csv('file', encoding = "ISO-8859-1")veya alternatif encoding = "utf-8"olarak okumak için ve genellikle utf-8için kullanıyorum to_csv.

Bunun yerine aliasgibi çeşitli seçeneklerden birini de kullanabilirsiniz ( karşılaşabileceğiniz çok sayıda kodlama için python dokümanlarına bakın ).'latin''ISO-8859-1'

Bkz ilgili Pandalar belgeleri , CSV dosyaları üzerinde piton docs örnekler ve burada SO üzerinde ilgili sorular bol. İyi bir arka plan kaynağı, her geliştiricinin unicode ve karakter kümeleri hakkında bilmesi gereken şeydir .

Kodlamayı tespit etmek için (dosyanın ascii olmayan karakterler içerdiğini varsayarak) enca( man sayfasına bakınız ) veya file -i(linux) veya file -I(osx) ( man sayfasına bakınız ) kullanabilirsiniz.


7
Bu bir Windows sorunu olduğundan, cp1252tercih edilebilir iso-8859-1.
17'de tzot 9:28

7
Teşekkürler pd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')benim için çalıştı
Mona Jalal

8
Sadece istisna olmadığı için, belirli bir kodlamanın doğru olduğunu körü körüne varsaymayın. Dizelere bakmanız ve yorumun mantıklı olup olmadığını anlamanız gerekir. Örneğin, "hors d'œuvre" yerine "hors d'½uvre" alırsanız, muhtemelen ISO-8859-1'den ISO-8859-15'e geçmeniz gerekir.
Joachim Wagner

6
benim için kodlama oldu ANSI. Bunu anlamak için, csv'yi açtım ve notepadtıklayın save as, orada kaydet düğmesinin yanındaki kodlamayı gösteriyor.
Vaibhav Vishal


68

En basit çözüm:

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')

Alternatif Çözüm:

  • Csv dosyasını Sublime metin düzenleyicisinde açın .
  • Dosyayı utf-8 biçiminde kaydedin.

Yüce'de Dosya -> Kodlama ile kaydet -> UTF-8'i tıklayın.

Ardından dosyanızı her zamanki gibi okuyabilirsiniz:

import pandas as pd
data = pd.read_csv('file_name.csv', encoding='utf-8')

ve diğer farklı kodlama türleri:

encoding = "cp1252"
encoding = "ISO-8859-1"

11
Soru, bu tür 30.000 dosyanın olduğunu açıklıyor. Her dosyayı manuel olarak açmak pratik olmaz.
Keith

4
en azından bir dosya için, bu benim için çalışıyor gibiydi!
apil.tamang

C motoru, kabul ettiği şeyde açıkça daha bağışlayıcıdır. Belirli bir CSV dosyası için iyi açılır encoding='iso-8859-1', bunun yerine engine='python'atar _csv.Error: field larger than field limit (131072).
Greg Bacon

1
kodlama ile tasarruf kullanmak için alternatif bir çözüm gerçekten yardımcı oldu! VSCode için nasıl kullanılacağı stackoverflow.com/questions/30082741/…
brownmagik352

20

Pandalar kodlamayı belirtmeye izin verir, ancak hatalı baytların otomatik olarak değiştirilmemesi hatalarının göz ardı edilmesine izin vermez. Bu nedenle , gerçek kullanım durumuna bağlı olarak tüm yönteme uyan farklı bir boyut yoktur .

  1. Kodlamayı biliyorsunuz ve dosyada kodlama hatası yok. Harika: sadece kodlamayı belirtmeniz gerekir:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
    
  2. Kodlama soruları ile uğraşmak istemezsiniz ve bazı metin alanları çöp içeriyor olsa da, sadece bu lanet dosyanın yüklenmesini istersiniz. Tamam, yalnızca Latin1kodlamayı kullanmanız gerekir çünkü giriş olarak olası bir baytı kabul eder (ve aynı kodun unicode karakterine dönüştürür):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
  3. Dosyanın çoğunun belirli bir kodlamayla yazıldığını biliyorsunuz, ancak kodlama hataları da içeriyor. Gerçek dünya örneği, utf8 olmayan bir düzenleyiciyle düzenlenen ve farklı kodlamaya sahip bazı satırlar içeren bir UTF8 dosyasıdır. Pandaların özel bir hata işleme için herhangi bir hükmü yoktur, ancak Python openişlevi (Python3 varsayarak) vardır ve read_csvdosya benzeri bir nesneyi kabul eder. Burada kullanılacak tipik hatalar parametresi, 'ignore'sadece rahatsız edici baytları ya 'backslashreplace'da rahatsız edici baytları Python'un ters eğik kaçış dizisiyle değiştiren (IMHO daha iyi) bastırır :

    file_encoding = 'utf8'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    input_fd = open(input_file_and_path, encoding=file_encoding, errors = 'backslashreplace')
    pd.read_csv(input_fd, ...)
    


14
with open('filename.csv') as f:
   print(f)

Bu kodu yürüttükten sonra 'filename.csv' kodlamasını bulacaksınız ve kodu aşağıdaki gibi yürütün

data=pd.read_csv('filename.csv', encoding="encoding as you found earlier"

işte gidiyorsun


6

Benim durumumda, bir dosya USC-2 LE BOMNotepad ++ göre kodlama var. Öyle encoding="utf_16_le"piton için.

Umarım, birisi için biraz daha hızlı bir cevap bulmaya yardımcı olur.


4

Benim durumumda bu python 2.7 için çalıştı:

data = read_csv(filename, encoding = "ISO-8859-1", dtype={'name_of_colum': unicode}, low_memory=False) 

Ve sadece python 3 için:

data = read_csv(filename, encoding = "ISO-8859-1", low_memory=False) 

3

Motoru = 'python' belirtmeyi deneyin. Benim için çalıştı ama hala nedenini anlamaya çalışıyorum.

df = pd.read_csv(input_file_path,...engine='python')

Bu da benim için çalıştı. Böylece kodlama = "ISO-8859-1" oldu. Kesinlikle bir kodlama sorunu. Elips karakteri (ör. "...") gibi ANSI'de özel bir karakter kodlanmışsa ve UTF-8'de okumaya çalışırsanız bir hata alabilirsiniz. Alt satırda, dosyanın oluşturulduğu kodlamayı bilmeniz gerekir.
Sean McCarthy

3

Güncellenmiş bir çözüm sağlamak ve bu sorunun neden ortaya çıkabileceğine ilişkin bir açıklama göndermek için yazıyorum. Diyelim ki bu verileri bir veritabanından veya Excel çalışma kitabından alıyorsunuz. Kodlama La Cañada Flintridge citykullanarak verileri dışa aktarmadığınız sürece, gibi özel karakterleriniz varsa, UTF-8hatalar sunacaksınız. La Cañada Flintridge cityolacak La Ca\xf1ada Flintridge city. pandas.read_csvVarsayılan parametrelerde ayarlama yapmadan kullanıyorsanız aşağıdaki hatayı alırsınız

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

Neyse ki, birkaç çözüm var.

1. Seçenek , dışa aktarmayı düzeltin. UTF-8Kodlama kullandığınızdan emin olun .

Seçenek 2 , dışa aktarma sorununu çözmüyorsanız ve kullanmanız gerekiyorsa pandas.read_csv, aşağıdaki parametreleri eklediğinizden emin olun engine='python'. Varsayılan olarak, pandalar engine='C'büyük temiz dosyaları okumak için harika olanı kullanır , ancak beklenmedik bir şey gelirse çökecektir. Deneyimlerime göre, ayar encoding='utf-8'bunu hiç çözmedi UnicodeDecodeError. Ayrıca, kullanmak zorunda değilsiniz errors_bad_lines, ancak GERÇEKTEN ihtiyacınız varsa bu hala bir seçenektir .

pd.read_csv(<your file>, engine='python')

Seçenek 3: Çözüm şahsen tercih ettiğim çözümdür. Vanilya Python kullanarak dosyayı okuyun.

import pandas as pd

data = []

with open(<your file>, "rb") as myfile:
    # read the header seperately
    # decode it as 'utf-8', remove any special characters, and split it on the comma (or deliminator)
    header = myfile.readline().decode('utf-8').replace('\r\n', '').split(',')
    # read the rest of the data
    for line in myfile:
        row = line.decode('utf-8', errors='ignore').replace('\r\n', '').split(',')
        data.append(row)

# save the data as a dataframe
df = pd.DataFrame(data=data, columns = header)

Umarım bu, bu sorunla ilk kez karşılaşan insanlara yardımcı olur.


2

Bir süre bununla uğraştım ve bu soruyu ilk arama sonucu olarak yayınlayacağımı düşündüm. Etiketleri encoding="iso-8859-1"pandalara eklemek read_csvişe yaramadı veya başka bir kodlama yapmadı, bir UnicodeDecodeError vermeye devam etti.

Bir dosya tanıtıcısı pd.read_csv(),geçiyorsanız, encodingözniteliği dosyaya değil açık olarak koymanız gerekir read_csv. Gez, ama izini sürmek için ince bir hata belli.


2

Lütfen eklemeyi deneyin

encoding='unicode_escape'

Bu yardımcı olacak. Benim için çalıştı. Ayrıca, doğru sınırlayıcı ve sütun adlarını kullandığınızdan emin olun.

Dosyayı hızlı bir şekilde yüklemek için sadece 1000 satır yüklemeye başlayabilirsiniz.


1

Bu yanıt, CSV kodlama sorunları için tümünü yakalama gibi görünüyor. Başlığınızda şöyle garip bir kodlama sorunu yaşıyorsanız:

>>> f = open(filename,"r")
>>> reader = DictReader(f)
>>> next(reader)
OrderedDict([('\ufeffid', '1'), ... ])

Sonra CSV dosyanızın başında bir bayt sırası işareti (BOM) karakteriniz olur. Bu cevap sorunu ele alıyor:

Python read csv - BOM ilk anahtara gömülü

Çözüm CSV'yi aşağıdakilerle yüklemektir encoding="utf-8-sig":

>>> f = open(filename,"r", encoding="utf-8-sig")
>>> reader = DictReader(f)
>>> next(reader)
OrderedDict([('id', '1'), ... ])

Umarım bu birine yardımcı olur.


1

Bu eski iş parçacığına bir güncelleme gönderiyorum. Çalışmış, ancak her dosyayı açmayı gerektiren bir çözüm buldum. CSV dosyamı LibreOffice'de açtım, Farklı Kaydet> filtre ayarlarını düzenle'yi seçtim. Açılır menüde UTF8 kodlamasını seçtim. Sonra ekledi encoding="utf-8-sig"için data = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig").

Umarım bu birine yardımcı olur.


Nisse, düzenleme için teşekkürler. Ne değiştirdiğini açıklayabilir misin? Bir fark görmüyorum.
tshirtdr1

1

Çevrimiçi bir bankadan indirilen basitleştirilmiş Çince bir CSV dosyasını açarken sorun yaşıyorum, denedim latin1, denedim iso-8859-1, denedim cp1252, hepsi boşuna.

Ama pd.read_csv("",encoding ='gbk')basitçe işe yarıyor.


0

Jupyter-notebook kullanıyorum. Benim durumumda, dosya yanlış biçimde gösteriliyordu. 'Kodlama' seçeneği çalışmıyor. Bu yüzden csv'yi utf-8 formatında kaydediyorum ve çalışıyor.


0

Bunu dene:

import pandas as pd
with open('filename.csv') as f:
    data = pd.read_csv(f)

Görünüşe göre kodlamayı açıkça argüman ile ifade etmeden halledecek gibi görünüyor


0

Pandalara geçmeden önce kodlamayı kontrol edin. Seni yavaşlatacak, ama ...

with open(path, 'r') as f:
    encoding = f.encoding 

df = pd.read_csv(path,sep=sep, encoding=encoding)

Python 3.7'de


0

Aynı hatayla sonuçlanan karşılaştığım bir diğer önemli sorun:

_values = pd.read_csv("C:\Users\Mujeeb\Desktop\file.xlxs")

^ Ben read_csv()yöntemi kullanarak bir excel dosyası okuyorum çünkü bu satır aynı hatayla sonuçlandı . read_excel().Xlxs okumak için kullanın


Vay be, herkes kodlama sorunları hakkında konuşuyor. Sorunum tuhaf görünüyordu.
Mujeeb Ishaque

Çünkü read_excelpandalarda bir tane var.
Ani Menon

0

Bunu deneyebilirsiniz.

import csv
import pandas as pd
df = pd.read_csv(filepath,encoding='unicode_escape')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.