J'utilise Python 3.2.1 et je ne peux pas importer le module StringIO
. J'utilise io.StringIO
et cela fonctionne, mais je ne peux pas l'utiliser avec numpy
'genfromtxt
comme ceci:
x="1 3\n 4.5 8"
numpy.genfromtxt(io.StringIO(x))
Je reçois l'erreur suivante:
TypeError: Can't convert 'bytes' object to str implicitly
et quand j'écris import StringIO
il dit
ImportError: No module named 'StringIO'
quand j'écris importer StringIO, il dit qu'il n'y a pas un tel module.
De Quoi de neuf dans Python 3. :
Les modules
StringIO
etcStringIO
ont disparu. Importez plutôt le moduleio
et utilisezio.StringIO
ouio.BytesIO
pour le texte et les données, respectivement.
.
Une méthode éventuellement utile pour corriger du code Python 2 à fonctionner également dans Python 3 (mise en garde):
try:
from StringIO import StringIO ## for Python 2
except ImportError:
from io import StringIO ## for Python 3
Remarque: Cet exemple peut être tangent au problème principal de la question et n'est inclus que comme élément à prendre en compte lors de la résolution générique du module manquant
StringIO
. Pour une solution plus directe le messageTypeError: Can't convert 'bytes' object to str implicitly
, voir cette réponse .
Dans mon cas j'ai utilisé:
from io import StringIO
Sur Python 3 numpy.genfromtxt
attend un flux d'octets. Utilisez le suivant:
numpy.genfromtxt(io.BytesIO(x.encode()))
Merci OP pour votre question et Roman pour votre réponse. J'ai dû chercher un peu pour trouver ceci; J'espère que ce qui suit aide les autres.
Python 2.7
Voir: 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.]]
"""
De plus:
dtype = "| Sx", où x = l'un quelconque des {1, 2, 3, ...}:
dtypes. Différence entre S1 et S2 en Python
"Les chaînes | S1 et | S2 sont des descripteurs de type de données; le premier signifie que le tableau contient des chaînes de longueur 1, les secondes de longueur 2. ..."
Le code de Roman Shapovalov devrait fonctionner dans Python 3.x ainsi que Python 2.6/2.7. Le voici encore avec l'exemple complet:
_import io
import numpy
x = "1 3\n 4.5 8"
numpy.genfromtxt(io.BytesIO(x.encode()))
_
Sortie:
_array([[ 1. , 3. ],
[ 4.5, 8. ]])
_
Explication de Python 3.x:
numpy.genfromtxt
_ prend un flux d'octets (un objet de type fichier interprété comme des octets au lieu d'Unicode).io.BytesIO
_ prend une chaîne d'octets et renvoie un flux d'octets. _io.StringIO
_, d'autre part, prendrait une chaîne Unicode et renverrait un flux Unicode.x
se voit attribuer un littéral de chaîne qui, dans Python 3.x, est une chaîne Unicode.encode()
prend la chaîne Unicode x
et en fait une chaîne d'octets, donnant ainsi à _io.BytesIO
_ un argument valide.La seule différence entre Python 2.6/2.7 est que x
est une chaîne d'octets (en supposant que _from __future__ import unicode_literals
_ n'est pas utilisé), puis encode()
prend la chaîne d'octets x
et continue de le faire. chaîne d'octets hors de celui-ci. Donc, le résultat est le même.
Comme il s’agit de l’une des questions les plus courantes de SO concernant StringIO
, voici quelques explications supplémentaires sur les instructions d’importation et les différentes versions de Python.
Voici les classes qui prennent une chaîne et retournent un flux:
io.BytesIO
(Python 2.6, 2.7 et 3.x) - Prend une chaîne d'octets. Renvoie un flux d'octets.io.StringIO
(Python 2.6, 2.7 et 3.x) - Prend une chaîne Unicode. Renvoie un flux Unicode.StringIO.StringIO
(Python 2.x) - Prend une chaîne d'octets ou une chaîne Unicode. Si chaîne d'octets, retourne un flux d'octets. Si chaîne Unicode, retourne un flux Unicode.cStringIO.StringIO
(Python 2.x) - Version plus rapide de _StringIO.StringIO
_, mais ne peut pas prendre de chaînes Unicode contenant des caractères non-ASCII.Notez que _StringIO.StringIO
_ est importé en tant que _from StringIO import StringIO
_, puis utilisé en tant que StringIO(...)
. Soit ça, soit vous faites _import StringIO
_ puis utilisez StringIO.StringIO(...)
. Le nom du module et le nom de la classe sont les mêmes. C'est semblable à datetime
de cette façon.
Quoi utiliser, en fonction de vos versions Python prises en charge:
Si vous ne supportez que Python 3.x: Utilisez simplement _io.BytesIO
_ ou _io.StringIO
_ en fonction de quel type des données avec lesquelles vous travaillez.
Si vous prenez en charge les deux Python 2.6/2.7 et 3.x, ou tentez de faire passer votre code de 2.6/2.7 à 3.x: L'option la plus simple reste d'utiliser _io.BytesIO
_ ou _io.StringIO
_. Bien que _StringIO.StringIO
_ soit flexible et semble donc préféré pour 2.6/2.7, cette flexibilité pourrait masquer les bogues qui se manifesteront dans 3.x. Par exemple, j'avais un code qui utilisait _StringIO.StringIO
_ ou _io.StringIO
_ en fonction de la version Python, mais je transmettais en fait une chaîne d'octets.Python 3.x, il a échoué et a dû être corrigé.
Un autre avantage de l'utilisation de _io.StringIO
_ est la prise en charge des nouvelles lignes universelles. Si vous transmettez le mot clé argument _newline=''
_ à _io.StringIO
_, il sera en mesure de fractionner les lignes de l'un des éléments _\n
_, _\r\n
_ ou _\r
_. J'ai trouvé que _StringIO.StringIO
_ retomberait sur _\r
_ en particulier.
Notez que si vous importez BytesIO
ou StringIO
from six
, vous obtenez _StringIO.StringIO
_ dans Python 2.x et la classe appropriée de io
dans Python. 3.x. Si vous êtes d’accord avec l’évaluation des paragraphes précédents, c’est en fait un cas dans lequel vous devriez éviter six
et simplement importer à partir de io
à la place.
Si vous supportez Python 2.5 ou moins et 3.x: , vous aurez besoin de _StringIO.StringIO
_ pour 2.5 ou moins, vous pouvez donc aussi utiliser six
. Cependant, sachez qu’il est généralement très difficile de prendre en charge les versions 2.5 et 3.x. Vous devez donc envisager de remplacer la version la moins prise en charge par la version 2.6 si possible.
Pour créer des exemples à partir de ici travailler avec Python 3.5.2, vous pouvez réécrire comme suit:
import io
data =io.BytesIO(b"1, 2, 3\n4, 5, 6")
import numpy
numpy.genfromtxt(data, delimiter=",")
La raison de la modification peut être que le contenu d'un fichier est sous forme de données (octets) qui ne créent pas de texte tant qu'elles ne sont pas décodées. genfrombytes
peut être un meilleur nom que genfromtxt
.