web-dev-qa-db-ja.com

Python3のStringIO

私はPython 3.2.1を使っていますがStringIOモジュールをインポートすることができません。私はio.StringIOを使っていますが、うまくいきますが、numpygenfromtxtと一緒に使うことはできません。

x="1 3\n 4.5 8"        
numpy.genfromtxt(io.StringIO(x))

次のようなエラーが表示されます。

TypeError: Can't convert 'bytes' object to str implicitly  

そして私がimport StringIOを書くときそれは言う

ImportError: No module named 'StringIO'
330
user1591744

私がインポートStringIOを書くとき、それはそのようなモジュールがないと言います。

From Python 3.0の新機能

StringIOcStringIOモジュールはなくなりました。代わりに、ioモジュールをインポートし、テキストとデータにそれぞれio.StringIOまたはio.BytesIOを使用してください。


いくつかのPython 2コードをPython 3でも動作するように修正するためのおそらく有用な方法(警告emptor):

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

注:この例は、問題の主な問題に接する可能性があり、欠落しているStringIOモジュールを包括的に扱うときに考慮すべき点としてのみ含まれています。 メッセージTypeError: Can't convert 'bytes' object to str implicitlyのより直接的な解決策については、 この回答を参照してください

563
nobar

私の場合、私は使ったことがあります:

from io import StringIO
93
Kamesh Jungi

Python 3ではnumpy.genfromtxtはバイトストリームを期待します。以下を使用してください。

numpy.genfromtxt(io.BytesIO(x.encode()))
61

ご質問ありがとうございます。ご回答ありがとうございます。これを見つけるには少し検索しなければなりませんでした。以下が他の人に役立つことを願っています。

Python 2.7

https://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html を参照してください。

import numpy as np
from StringIO import StringIO

data = "1, abc , 2\n 3, xxx, 4"

print type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", dtype="|S3", autostrip=True)
"""
[['1' 'abc' '2']
 ['3' 'xxx' '4']]
"""

print '\n', type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

Python 3.5:

import numpy as np
from io import StringIO
import io

data = "1, abc , 2\n 3, xxx, 4"
#print(data)
"""
1, abc , 2
 3, xxx, 4
"""

#print(type(data))
"""
<class 'str'>
"""

#np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
# TypeError: Can't convert 'bytes' object to str implicitly

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", dtype="|S3", autostrip=True))
"""
[[b'1' b'abc' b'2']
 [b'3' b'xxx' b'4']]
"""

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", autostrip=True))
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

余談:

dtype = "| Sx"、ここでx = {1、2、3、...}のいずれか。

dtypes。 PythonにおけるS1とS2の違い

「| S1と| S2の文字列はデータ型記述子です。最初の文字列は長さ1の文字列を保持し、2番目の文字列は長さ2の文字列を保持します。

22
Victoria Stuart

six モジュールから StringIO を使用できます。

import six
import numpy

x = "1 3\n 4.5 8"
numpy.genfromtxt(six.StringIO(x))
14
Tiago Coutinho

Roman ShapovalovのコードはPython 3.xおよびPython 2.6/2.7で動作するはずです。これもまた完全な例です。

import io
import numpy
x = "1 3\n 4.5 8"
numpy.genfromtxt(io.BytesIO(x.encode()))

出力:

array([[ 1. ,  3. ],
       [ 4.5,  8. ]])

Python 3.xの説明:

  • numpy.genfromtxtはバイトストリーム(Unicodeの代わりにバイトとして解釈されるファイルのようなオブジェクト)を取ります。
  • io.BytesIOはバイト文字列を取り、バイトストリームを返します。一方、io.StringIOは、Unicode文字列を受け取り、Unicodeストリームを返します。
  • xは文字列リテラルを割り当てられます。これはPython 3.xではUnicode文字列です。
  • encode()はUnicode文字列xを取り出し、それからバイト文字列を取り出します。したがって、io.BytesIOに有効な引数を与えます。

Python 2.6/2.7の唯一の違いは、xはバイト文字列であり(from __future__ import unicode_literalsが使用されていないと仮定して)、encode()はバイト文字列xを取り出し、それでも同じバイト文字列を取り出すことです。だから結果は同じです。


これはStringIOに関するSOの最も一般的な質問の1つなので、importステートメントとさまざまなPythonバージョンについてのもう少し説明があります。

これが文字列を受け取りストリームを返すクラスです:

  • io.BytesIO (Python 2.6、2.7、および3.x) - バイト文字列を受け取ります。バイトストリームを返します。
  • io.StringIO (Python 2.6、2.7、および3.x) - Unicode文字列を取ります。 Unicodeストリームを返します。
  • StringIO.StringIO (Python 2.x) - バイト文字列またはUnicode文字列を取ります。バイト文字列の場合、バイトストリームを返します。 Unicode文字列の場合、Unicodeストリームを返します。
  • cStringIO.StringIO (Python 2.x) - StringIO.StringIOの高速版ですが、非ASCII文字を含むUnicode文字列は使えません。

StringIO.StringIOfrom StringIO import StringIOとしてインポートされ、StringIO(...)として使用されることに注意してください。どちらか、またはimport StringIOを実行してからStringIO.StringIO(...)を使用します。モジュール名とクラス名はたまたま同じです。その点ではdatetimeに似ています。

サポートされているPythonのバージョンに応じて、使用するもの

  • Python 3.xのみをサポートしている場合は、 使用しているデータの種類に応じてio.BytesIOまたはio.StringIOを使用してください。

  • Python 2.6/2.7と3.xの両方をサポートしている場合、またはコードを2.6/2.7から3.xに移行しようとしている場合: それでもio.BytesIOまたはio.StringIOを使用するのが最も簡単な方法です。 StringIO.StringIOは柔軟で2.6/2.7には好まれるように見えますが、その柔軟性は3.xで現れるバグを隠すことができます。たとえば、Pythonのバージョンに応じてStringIO.StringIOまたはio.StringIOを使用するコードがありましたが、実際にはバイト文字列を渡していたので、Python 3.xでテストすることにしたときに失敗し、修正する必要がありました。

    io.StringIOを使用するもう1つの利点は、ユニバーサル改行のサポートです。キーワード引数newline=''io.StringIOに渡すと、\n\r\n、または\rのいずれかで行を分割することができます。私はStringIO.StringIOが特に\rをトリップすることを発見しました。

    BytesIO からStringIOまたはsixをインポートすると、Python 2.xではStringIO.StringIOを、Python 3.xではioから適切なクラスを取得することに注意してください。前の段落の評価に同意するのであれば、これは実際にはsixを避けてioからインポートするだけの場合です。

  • Python 2.5以下および3.xをサポートしている場合: 2.5以下の場合はStringIO.StringIOが必要になるので、sixを使用することもできます。しかし、2.5と3.xの両方をサポートするのは一般的に非常に困難であることを認識してください。そのため、可能であれば、サポートされている最低バージョンを2.6にアップグレードすることを検討する必要があります。

8
S. Kirby

here の例をPython 3.5.2で動作させるためには、次のように書き換えることができます。

import io
data =io.BytesIO(b"1, 2, 3\n4, 5, 6") 
import numpy
numpy.genfromtxt(data, delimiter=",")

変更の理由は、ファイルの内容が何らかの理由でデコードされるまでテキストを作成しないデータ(バイト)にあるためかもしれません。 genfrombytesgenfromtxtより良い名前かもしれません。

6