いくつかのコードをPython2からPython3に移動しています。
文字列の処理方法に影響を与える「unicode」と「bytes」の全体的な変更を認識しています(Python 3ではデフォルトでunicode)。
ただし、関数のconverters
コールバックでnumpyがそれらを処理する方法にいくつかの矛盾が見つかりましたgenfromtxt
。
データファイル(data.txt)について考えてみましょう。
1,2,hello!
3,4,world!
文字列を読み、「!」を削除したい covnerterで。Python 2では、次のことを行いました。
np.genfromtxt('data.txt', delimiter=',', dtype='i4,i4,S10',
converters={2:lambda s: s.strip('!')})
これは正常に動作します。Python 3の場合、データがバイト配列ではなくユニコードとして読み込まれるように、dtypesでS10をU10に変更しただけです。
np.genfromtxt('data.txt', delimiter=',', dtype='i4,i4,U10',
converters={2:lambda s: s.strip('!')})
ただし、コンバータは次のエラーで失敗します。 TypeError: a bytes-like object is required, not 'str'
コンバーター機能は、Unicode文字列ではなく、バイト配列をまだ受信しているようです。これを機能させる唯一の方法は、次のように変更s.strip('!')
することです。s.strip(b'!')
これは私には矛盾しているようです。特に私はstripコマンドを実行した場合、それは罰金を作品として、AFTER私はむしろコンバータとしてよりも、配列を読み取り、すなわち、これはうまく動作します:
dat=np.genfromtxt('data.txt', delimiter=',', dtype='i4,i4,U10')
print(dat.dtype)
print(dat['f2'][0].strip('!') # notice, no 'b' needed
プリント:
[('f0', '<i4'), ('f1', '<i4'), ('f2', '<U10')]
hello
これは私には矛盾しているように思われ、前述のエラーを回避するために「b」指定子をいつ使用するかを知ることを困難にしています!
Python 3では、Unicodeとバイトの問題全体が非常に苛立たしいことに気づきました。
ファイルを開くモードによって異なります。Py2との互換性のgenfromtxt
ために、常にバイトモードで動作するために使用されます。これで、Py3は「テキスト」モードで開くことができます
encoding
パラメータの追加(ここでNone
は十分です。ファイルはUTF8として保存されます):
In [373]: np.genfromtxt('stack54570492.txt', delimiter=',', dtype='i4,i4,S10',
...: converters={2:lambda s: s.strip('!')}, encoding=None)
Out[373]:
array([(1, 2, b'hello'), (3, 4, b'world')],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', 'S10')])
(このパラメーターの詳細については、ドキュメントを参照してください。)
コンバーターは、を割り当てようとする前に、「raw」文字列に適用されdtype
ます。あなたが指定したかどうかは関係ありませんので、U10
かS10
。多くの場合、文字列を数値に変換できるようにクリーンアップするために使用されるコンバーター。
後処理の場合b
でも、dtypeに応じて、が必要です。
In [376]: dat=np.genfromtxt('stack54570492.txt', delimiter=',', dtype='i4,i4,S10')
In [377]: dat
Out[377]:
array([(1, 2, b'hello!'), (3, 4, b'world!')],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', 'S10')])
In [378]: dat['f2'][0].strip('!')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-378-697f391eaffc> in <module>()
----> 1 dat['f2'][0].strip('!')
TypeError: a bytes-like object is required, not 'str'
In [379]: dat['f2'][0].strip(b'!')
Out[379]: b'hello'
の完全なヘルプencoding
:
エンコーディング:str、オプション
入力ファイルのデコードに使用されるエンコード。が
fname
ファイルオブジェクトの場合は適用されません。特別な値 'bytes'は、可能な場合にバイト配列を受け取り、latin1でエンコードされた文字列をコンバーターに渡すことを保証する下位互換性の回避策を有効にします。この値をオーバーライドして、Unicode配列を受け取り、コンバーターへの入力として文字列を渡します。Noneに設定すると、システムのデフォルトが使用されます。デフォルト値は「バイト」です。.. versionadded :: 1.14.0
'bytes'エンコーディングでは、b'!'
(指定されたdtypeに関係なく)コンバーターでが必要です。
In [382]: np.genfromtxt('stack54570492.txt', delimiter=',', dtype=None,
...: converters={2:lambda s: s.strip(b'!')}, encoding='bytes')
Out[382]:
array([(1, 2, b'hello'), (3, 4, b'world')],
dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', 'S5')])
In [383]: np.genfromtxt('stack54570492.txt', delimiter=',', dtype=None,
...: converters={2:lambda s: s.strip('!')}, encoding=None)
Out[383]:
array([(1, 2, 'hello'), (3, 4, 'world')],
dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<U5')])
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加