119

非標準文字を含む非常に大きなデータセットを操作しようとしています。仕事の仕様に従って、ユニコードを使用する必要がありますが、困惑しています。(そして、おそらくすべて間違っています。)

次を使用して CSV を開きます。

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

次に、次のようにエンコードしようとします。

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])

API に送信する必要があるため、緯度と経度を除くすべてをエンコードしています。プログラムを実行してデータセットを解析して使用できるものにすると、次のトレースバックが表示されます。

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)

私はpython 2.7.2を使用していることを伝えるべきだと思います.これはdjango 1.4でビルドされたアプリの一部です. このトピックに関するいくつかの投稿を読みましたが、どれも直接適用されるようには見えません。どんな助けでも大歓迎です。

また、問題の原因となっている非標準文字の一部が Ñ であり、場合によっては É であることを知りたい場合もあります。

4

11 に答える 11

160

Unicode は UTF-8 と等しくありません。後者は前者の単なるエンコーディングです。

あなたはそれを間違った方法でやっています。UTF-8でエンコードされたデータを読み取っているため、UTF-8 でエンコードされた文字列を Unicode 文字列にデコードする必要があります。

したがって、 に置き換えるだけ.encode.decode動作するはずです (.csv が UTF-8 でエンコードされている場合)。

とはいえ、何も恥ずかしいことではありません。プログラマーの 5 人に 3 人は、最初はこれを理解するのに苦労したに違いありません ;)

更新: 入力データがUTF-8 でエンコードされていない.decode()場合は、当然、適切なエンコードを使用する必要があります。何も指定されていない場合、Python は ASCII を想定しますが、非 ASCII 文字では明らかに失敗します。

于 2012-05-02T00:21:01.067 に答える
92

この行をコードに追加するだけです:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
于 2016-10-31T17:00:11.207 に答える
3

コンピューターのロケールが正しく設定されていませんでした。

私が最初にやった

>>> import locale
>>> locale.getpreferredencoding(False)
'ANSI_X3.4-1968'

locale.getpreferredencoding(False)open()encoding を指定しない場合に呼び出される関数です。出力は になるはずです'UTF-8'が、この場合は ASCII の変形です

次に、bash コマンドを実行したlocaleところ、この出力が得られました

$ locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

そのため、私はデフォルトの Ubuntu ロケールを使用していました。これにより、Python はファイルを UTF-8 ではなく ASCII として開きます。ロケールをに設定する必要がありましたen_US.UTF-8

sudo apt install locales 
sudo locale-gen en_US en_US.UTF-8    
sudo dpkg-reconfigure locales

システム全体でロケールを変更できない場合は、次のようにすべての Python コードを呼び出すことができます。

PYTHONIOENCODING="UTF-8" python3 ./path/to/your/script.py

またはする

export PYTHONIOENCODING="UTF-8"

それを実行するシェルに設定します。

于 2019-12-11T19:39:05.207 に答える
3

Python 3 ユーザーの場合:

エンコーディングを「ascii」から「latin1」に変更すると機能します。

また、以下のスニペットを使用して上位 10000 バイトを読み取って、エンコードを自動的に検出することもできます。

import chardet  
with open("dataset_path", 'rb') as rawdata:  
            result = chardet.detect(rawdata.read(10000))  
print(result)
于 2018-03-29T23:58:35.407 に答える
0

Docker コンテナー内でこの問題に対処します。(私の場合のように) ロケールを生成するだけで、それ以上何もする必要がない場合もあります。

sudo locale-gen en_US en_US.UTF-8

場合によっては、ロケールが既にインストールおよび構成されているため、それで十分でした。ロケールをインストールして構成する必要がある場合は、次の部分を Dockerfile に追加します。

RUN apt update && apt install locales && \
    sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
    echo 'LANG="en_US.UTF-8"'>/etc/default/locale && \
    dpkg-reconfigure --frontend=noninteractive locales && \
    update-locale LANG=en_US.UTF-8

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
ENV LC_ALL en_US.UTF-8

私はこのようにそれをテストしました:

cat <<EOF > /tmp/test.txt
++*=|@#|¼üöäàéàè!´]]¬|¢|¢¬|{ł|¼½{}}
EOF

python3
import pathlib; pathlib.Path("/tmp/test.txt").read_text()
于 2021-09-15T13:03:44.653 に答える