2012-05-02 27 views
60

Estoy intentando trabajar con un conjunto de datos muy grande que tiene algunos caracteres no estándar. Necesito usar Unicode, según las especificaciones del trabajo, pero estoy desconcertado. (Y muy posiblemente haciendo todo mal.)UnicodeDecodeError: el códec 'ascii' no puede decodificar el byte 0xd1 en la posición 2: ordinal no está dentro del rango (128)

que abrir el CSV usando:

15  ncesReader = csv.reader(open('geocoded_output.csv', 'rb'), delimiter='\t', quotechar='"') 

Entonces, intento para codificar con:

name=school_name.encode('utf-8'), street=row[9].encode('utf-8'), city=row[10].encode('utf-8'), state=row[11].encode('utf-8'), zip5=row[12], zip4=row[13],county=row[25].encode('utf-8'), lat=row[22], lng=row[23]) 

estoy codificación de todo, excepto la lat y lng porque deben enviarse a una API. Cuando ejecuto el programa para analizar el conjunto de datos en lo que puedo usar, obtengo el siguiente Traceback.

Traceback (most recent call last): 
    File "push_into_db.py", line 80, in <module> 
    main() 
    File "push_into_db.py", line 74, in main 
    district_map = buildDistrictSchoolMap() 
    File "push_into_db.py", line 32, in buildDistrictSchoolMap 
    county=row[25].encode('utf-8'), lat=row[22], lng=row[23]) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 2: ordinal not in range(128) 

creo que debo decirle que estoy usando Python 2.7.2, y esto es parte de una aplicación a construir en Django 1.4. He leído varias publicaciones sobre este tema, pero ninguna de ellas parece aplicarse directamente. Cualquier ayuda será apreciada.

Es posible que también desee saber que algunos de los caracteres no estándar que causan el problema son Ñ y posiblemente É.

+1

¿Cuál es su codificación archivo original? Creo que debes decodificarlo de acuerdo con la codificación original y luego convertir a utf 8 –

+0

posible duplicado de [Codificación da "codec 'ascii' no puede codificar el carácter ... ordinal no en rango (128)"] (http: // stackoverflow .com/questions/2513027/encoding-gives-ascii-codec-cant-encode-character-ordinal-not-in-range128) [Ed .: y de aproximadamente un billón de otros, también, estoy seguro.] –

Respuesta

119

Unicode no es igual a UTF-8. Esta última es solo una que codifica para la primera.

Lo está haciendo de manera incorrecta. Usted es leyendo UTF-8- datos codificados, por lo que tiene que decodificar la cadena codificada en UTF-8 en una cadena unicode.

Así que simplemente reemplace .encode con .decode, y debería funcionar (si su .csv tiene codificación UTF-8).

No hay nada de qué avergonzarse, sin embargo. Apuesto a 3 de cada 5 programadores tenían problemas al principio entender esto, si no más;)

Actualización: Si los datos de entrada es no codificación UTF-8, entonces usted tiene que .decode() con la codificación adecuada, por supuesto . Si no se proporciona nada, Python asume ASCII, que obviamente falla en caracteres que no son ASCII.

+0

The La razón del error es que Python está tratando de decodificarlo automáticamente desde la codificación predeterminada, ASCII, para que luego pueda codificarlo como lo especificó, a UTF-8. Como los datos no son válidos ASCII, no funcionan. – agf

+7

seguro, pero si se trata de datos codificados * UTF8- * (como supongo), entonces '.decode ('utf-8')' debería ser el truco, ¿no? – ch3ka

+0

Claro, probablemente tienes razón. Solo estaba explicando por qué obtienes ese error específico en esta situación. – agf

48

Sólo tiene que añadir estas líneas a sus códigos:

import sys 
reload(sys) 
sys.setdefaultencoding('utf-8') 
+2

gracias, esto esté arreglado mi problema –

+0

'AttributeError: módulo 'sys' no tiene atributo 'setdefaultencoding' no parecen funcionar en Python 3 – skjerns

1

La principal razón para el error es que la codificación predeterminada asumida por el pitón es ASCII. Por lo tanto, si los datos de cadena que se codificarán con encode('utf8') contienen caracteres que están fuera del rango ASCII, p. para una cadena como 'hgvcj 터 파크 387', python arrojaría un error porque la cadena no está en el formato de codificación esperado.

Si está utilizando la versión de Python anteriores a la versión 3.5, una solución fiable sería establecer la codificación predeterminada asumida por el pitón a utf8:

import sys 
reload(sys) 
sys.setdefaultencoding('utf8') 
name = school_name.encode('utf8') 

De esta manera pitón sería capaz de anticipar caracteres dentro de una cadena que quedan fuera del rango ASCII.

Sin embargo, si está utilizando la versión 3 de python.5 o superior, la función reload() no está disponible, por lo que tendría que arreglarlo usando decodificación, p. Ej.

name = school_name.decode('utf8').encode('utf8') 
+0

¿cuál es la diferencia entre la respuesta y la mía –

+0

Más detallado. A menudo las personas encuentran útiles los detalles causales. Y su código funciona por cierto, sin derogación prevista. –

+0

recargar está disponible en Python 3, solo tendría que importarlo. de la imp importación de recarga – Meow

2

para Python 3 usuarios. que puede hacer

with open(csv_name_here, 'r', encoding="utf-8") as f: 
    #some codes 

funciona con el frasco también :)

+0

gracias señor! eso solucionó mi problema – fuzunspm

+0

Es la primera vez que ayudo a alguien aquí. se siente bien sabiendo que ayudé :) – screaminghard

Cuestiones relacionadas