UnicodeDecodeError: 'ascii'コーデックは13番目のバイト0xe2をデコードできません:序数が範囲(128)にありません


129

NLTKを使用して、各行がドキュメントと見なされるテキストファイルでkmeansクラスタリングを実行しています。たとえば、私のテキストファイルは次のようになります。

belong finger death punch <br>
hasty <br>
mike hasty walls jericho <br>
jägermeister rules <br>
rules bands follow performing jägermeister stage <br>
approach 

今私が実行しようとしているデモコードはこれです:

import sys

import numpy
from nltk.cluster import KMeansClusterer, GAAClusterer, euclidean_distance
import nltk.corpus
from nltk import decorators
import nltk.stem

stemmer_func = nltk.stem.EnglishStemmer().stem
stopwords = set(nltk.corpus.stopwords.words('english'))

@decorators.memoize
def normalize_word(word):
    return stemmer_func(word.lower())

def get_words(titles):
    words = set()
    for title in job_titles:
        for word in title.split():
            words.add(normalize_word(word))
    return list(words)

@decorators.memoize
def vectorspaced(title):
    title_components = [normalize_word(word) for word in title.split()]
    return numpy.array([
        word in title_components and not word in stopwords
        for word in words], numpy.short)

if __name__ == '__main__':

    filename = 'example.txt'
    if len(sys.argv) == 2:
        filename = sys.argv[1]

    with open(filename) as title_file:

        job_titles = [line.strip() for line in title_file.readlines()]

        words = get_words(job_titles)

        # cluster = KMeansClusterer(5, euclidean_distance)
        cluster = GAAClusterer(5)
        cluster.cluster([vectorspaced(title) for title in job_titles if title])

        # NOTE: This is inefficient, cluster.classify should really just be
        # called when you are classifying previously unseen examples!
        classified_examples = [
                cluster.classify(vectorspaced(title)) for title in job_titles
            ]

        for cluster_id, title in sorted(zip(classified_examples, job_titles)):
            print cluster_id, title

(これもここにあります

私が受け取るエラーはこれです:

Traceback (most recent call last):
File "cluster_example.py", line 40, in
words = get_words(job_titles)
File "cluster_example.py", line 20, in get_words
words.add(normalize_word(word))
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/nltk/decorators.py", line 183, in memoize
result = func(*args)
File "cluster_example.py", line 14, in normalize_word
return stemmer_func(word.lower())
File "/usr/local/lib/python2.7/dist-packages/nltk/stem/snowball.py", line 694, in stem
word = (word.replace(u"\u2019", u"\x27")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 13: ordinal not in range(128)

ここで何が起きてるの?

回答:


133

ファイルはstrsの束として読み取られていますが、sである必要がありますunicode。Pythonは暗黙的に変換を試みますが、失敗します。変化する:

job_titles = [line.strip() for line in title_file.readlines()]

strs を明示的にデコードするにはunicode(ここではUTF-8を想定):

job_titles = [line.decode('utf-8').strip() for line in title_file.readlines()]

モジュールをインポートcodecscodecs.openて組み込みではなくを使用することで解決することもできますopen


2
このline.decode( 'utf-8')。strip()。lower()。split()を実行しても、同じエラーが発生します。私は.deocode( 'utf-8')を追加しました
Aman Mathur

@kathirraja:そのリファレンスを提供できますか?私の知る限り、Python 3でもdecode、バイト文字列をUnicode文字列にデコードする方法として、この方法が依然として好まれています。(ただし、私の答えでタイプは右のPython 3のためではありません- Pythonの3のために、我々はから変換しようとしているbytesstrではなく、strunicode。)
icktoofay

52

これは私にとってはうまくいきます。

f = open(file_path, 'r+', encoding="utf-8")

3番目のパラメーターエンコーディングを追加して、エンコーディングタイプが 'utf-8'であることを確認できます。

注:このメソッドはPython3で正常に動作します。Python2.7では試していません。


Python 2.7.10では機能しません:TypeError: 'encoding' is an invalid keyword argument for this function
Borhan Kazimipour

2
:それは、Python 2.7.10で動作しませんTypeError: 'encoding' is an invalid keyword argument for this function :これは罰金に動作しますimport io with io.open(file_path, 'r', encoding="utf-8") as f: for line in f: do_something(line)
Borhan Kazimipour

2
python3.6の魅力のように動作しましたありがとうございました!
SRC

32

私にとって、端末のエンコーディングに問題がありました。.bashrcにUTF-8を追加すると、問題が解決しました。

export LC_CTYPE=en_US.UTF-8

後で.bashrcをリロードすることを忘れないでください:

source ~/.bashrc

3
export LC_ALL=C.UTF-8Ubuntu 18.04.3とPython 3.6.8 を使用する必要がありました。そうでなければ、これは私の問題を解決しました、ありがとう。
jbaranski

31

あなたもこれを試すことができます:

import sys
reload(sys)
sys.setdefaultencoding('utf8')

3
これの意味は何ですか?それは何かグローバルなもののようで、このファイルだけに適用できるわけではありません。
simeg 2017

2
上記のPython 3では非推奨とされていることに注意してください
gented

12

Ubuntu 18.04でPython3.6を使用しているとき、私は両方の問題を解決しました:

with open(filename, encoding="utf-8") as lines:

ツールをコマンドラインとして実行している場合:

export LC_ALL=C.UTF-8

Python2.7を使用している場合は、これを別の方法で処理する必要があることに注意してください。最初に、デフォルトのエンコーディングを設定する必要があります。

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

次にio.open、エンコーディングの設定に使用する必要があるファイルをロードします。

import io
with io.open(filename, 'r', encoding='utf-8') as lines:

あなたはまだ環境をエクスポートする必要があります

export LC_ALL=C.UTF-8

6

DockerコンテナーにPythonパッケージをインストールしようとすると、このエラーが発生しました。私にとっての問題は、Dockerイメージがlocale構成されていないことでした。Dockerfileに次のコードを追加すると、問題が解決しました。

# Avoid ascii errors when reading files in Python
RUN apt-get install -y \
  locales && \
  locale-gen en_US.UTF-8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'

私はこれを使わなければなりませんでした
Mayrop

3

関連するすべておよびすべてのUnicodeエラーを見つけるには...次のコマンドを使用します。

grep -r -P '[^\x00-\x7f]' /etc/apache2 /etc/letsencrypt /etc/nginx

で見つけた

/etc/letsencrypt/options-ssl-nginx.conf:        # The following CSP directives don't use default-src as 

を使用してshed、問題のあるシーケンスを見つけました。編集者の間違いであることが判明しました。

00008099:     C2  194 302 11000010
00008100:     A0  160 240 10100000
00008101:  d  64  100 144 01100100
00008102:  e  65  101 145 01100101
00008103:  f  66  102 146 01100110
00008104:  a  61  097 141 01100001
00008105:  u  75  117 165 01110101
00008106:  l  6C  108 154 01101100
00008107:  t  74  116 164 01110100
00008108:  -  2D  045 055 00101101
00008109:  s  73  115 163 01110011
00008110:  r  72  114 162 01110010
00008111:  c  63  099 143 01100011
00008112:     C2  194 302 11000010
00008113:     A0  160 240 10100000


0

Python 3の場合、デフォルトのエンコーディングは「utf-8」になります。次の手順は、ベースドキュメントで推奨されています。問題が発生した場合は、https//docs.python.org/2/library/csv.html#csv-examples

  1. 関数を作成する

    def utf_8_encoder(unicode_csv_data):
        for line in unicode_csv_data:
            yield line.encode('utf-8')
    
  2. 次に、リーダー内の関数を使用します。

    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data))

0

python3x以降

  1. バイトストリームでファイルをロードする:

    body = '' open( 'website / index.html'、 'rb')の行の場合:decodeLine = lines.decode( 'utf-8')body = body + decodedLine.strip()return body

  2. グローバル設定を使用:

    import io import sys sys.stdout = io.TextIOWrapper(sys.stdout.buffer、encoding = 'utf-8')


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.