Я использую Python 3.2.1 и не могу импортировать модуль StringIO
. Я использую
io.StringIO
и он работает, но я не могу использовать его с numpy
's genfromtxt
, как это происходит в данном случае:
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'
Когда я пишу import StringIO, он говорит, что такого модуля не существует.
Модули
StringIO
иcStringIO
исчезли. Вместо них импортируйте модульio
модуль и используйтеio.StringIO
илиio.BytesIO
для работы с текстом и данными соответственно.
.
Возможно, полезный метод исправления некоторого кода на Python 2 для работы в Python 3 (осторожно):
try:
from StringIO import StringIO ## for Python 2
except ImportError:
from io import StringIO ## for Python 3
Примечание: Этот пример может быть косвенным по отношению к основной проблеме вопроса и приведен только как то, что можно рассмотреть при общем решении проблемы отсутствия модуля
StringIO
. Для более прямого решения проблемы сообщениеTypeError: Can't convert 'bytes' object to str implicitly
, смотрите этот ответ.
В моем случае я использовал:
from io import StringIO
На Python 3 numpy.genfromtxt
ожидает поток байтов. Используйте следующее:
numpy.genfromtxt(io.BytesIO(x.encode()))
Спасибо OP за ваш вопрос, и Роман за ваш ответ. Мне пришлось немного искать, чтобы найти это; Я надеюсь, что следующее поможет другим.
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, ...}:
https://stackoverflow.com/questions/14790130/dtypes-difference-between-s1-and-s2-in-python
«Струнки | S1 и | S2 являются дескрипторами типа данных; первый означает, что массив содержит строки длиной 1, второй длины 2. ...«
Код Романа Шаповалова должен работать на 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()))
Вывод:
& Лт;!- язык: lang-none - >
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
является строкой байта (при условии, чтоиз __future__ import unicode_literals
не используется), а затем encode ()
принимает строку байта x
и все еще делает тот же строка байта из него. Таким образом, результат тот же.
Поскольку это один из самых популярных вопросов SO, касающихся «StringIO», вот еще несколько объяснений операторов импорта и различных версий 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
, но не может принимать строки Unicode, содержащие символы не ASCII.Обратите внимание, что StringIO.StringIO
импортируется как из StringIO import StringIO
, затем используется как StringIO (...)
. Либо так, либо вы делаете import StringIO
, а затем используете StringIO.StringIO (...)
. Имя модуля и имя класса просто совпадают. Это похоже на «в то время».
Что использовать, в зависимости от поддерживаемых вами версий Python:
io.BytesIO
или io.StringIO
в зависимости от того, с какими данными вы работаете.io.BytesIO
или io.StringIO
. Хотя StringIO.StringIO
является гибким и, следовательно, кажется предпочтительным для 2.6 / 2.7, эта гибкость может маскировать ошибки, которые будут проявляться в 3.x. Например, у меня был какой-то код, который использовал StringIO.StringIO
или io.StringIO
в зависимости от версии Python, но я фактически передавал строку байта, поэтому, когда я приступил к тестированию в Python 3.x, она не удалась и должен был быть исправлен.Еще одним преимуществом использования io.StringIO
является поддержка универсальных новых линий. Если вы передадите аргумент ключевого слова newline = ''
в io.StringIO
, он сможет разделять строки в любом из \ n
, \ r \ n
или \ r
. Я обнаружил, что StringIO.StringIO
будет особенно \ r
.
Обратите внимание, что если вы импортируете BytesIO
или StringIO
из six
, вы получаете StringIO.StringIO
в Python 2.x и соответствующий класс из io
в Python 3.x. Если вы согласны с оценкой моих предыдущих параграфов, это на самом деле один случай, когда вам следует избегать «шести» и просто импортировать из «io».
StringIO.StringIO
для 2.5 или ниже, так что вы можете также использовать six
. Но поймите, что, как правило, очень сложно поддерживать 2.5 и 3.x, поэтому вам следует рассмотреть возможность объединения вашей самой низкой поддерживаемой версии с 2.6, если это вообще возможно.Чтобы сделать примеры из здесь работать с Python 3.5.2, вы можете переписать следующим образом:
import io
data =io.BytesIO(b"1, 2, 3\n4, 5, 6")
import numpy
numpy.genfromtxt(data, delimiter=",")
Причиной изменения может быть то, что содержимое файла находится в данных (байтах), которые не создают текст до тех пор, пока не будут каким-то образом декодированы. genfrombytes
может быть лучшим именем, чем genfromtxt
.
попробуй это
из StringIO импорт StringIO
x = "1 3 \ n 4,5 8"
numpy.genfromtxt (StringIO (x))