如何在 Python3 中使用 StringIO 来执行 numpy.genfromtxt()?
- 2025-01-08 08:50:00
- admin 原创
- 139
问题描述:
我使用的是 Python 3.2.1,无法导入StringIO
模块。我使用它io.StringIO
,它可以工作,但我不能将它与numpy
's一起使用genfromtxt()
,如下所示:
x="1 3
4.5 8"
numpy.genfromtxt(io.StringIO(x))
我收到以下错误:
TypeError: Can't convert 'bytes' object to str implicitly
当我写的时候import StringIO
它说
ImportError: No module named 'StringIO'
解决方案 1:
当我写 import StringIO 时,它说没有这样的模块。
来自Python 3.0 的新功能:
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
,请参阅此答案。
解决方案 2:
就我而言,我使用了:
from io import StringIO
解决方案 3:
在 Python 3 上numpy.genfromtxt
需要字节流。使用以下命令:
numpy.genfromtxt(io.BytesIO(x.encode()))
解决方案 4:
Roman Shapovalov 的代码应该可以在 Python 3.x 以及 Python 2.6/2.7 中运行。下面是完整的示例:
import io
import numpy
x = "1 3
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
并仍然从中生成相同的字节字符串。所以结果是相同的。
由于这是 SO 上最受欢迎的问题之一StringIO
,因此这里对 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.StringIO
将作为 导入from 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 中会出现的错误。例如,我有一些代码使用StringIO.StringIO
或io.StringIO
取决于 Python 版本,但我实际上传递了一个字节字符串,所以当我在 Python 3.x 中测试它时它失败了并且必须修复。
使用的另一个优点io.StringIO
是支持通用换行符。如果你将关键字参数传递newline=''
给io.StringIO
,它将能够在`、
或上拆分行
。我发现尤其
StringIO.StringIO会在 上出错。
`
请注意,如果您 importBytesIO
或StringIO
from six
,则会StringIO.StringIO
在 Python 2.x 中获得相应的类,而在 Python 3.x 中获得相应的类 from 。io
如果您同意我前面几段的评估,那么这实际上是您应该避免的一种情况six
,而只需 import fromio
即可。
如果您支持 Python 2.5 或更低版本和 3.x:您需要
StringIO.StringIO
2.5 或更低版本,因此您不妨使用six
。但请注意,同时支持 2.5 和 3.x 通常非常困难,因此您应该考虑尽可能将最低支持版本提升至 2.6。
解决方案 5:
谢谢楼主的提问,也谢谢 Roman 的回答。我搜索了一番才找到这个;希望下面的内容能对其他人有所帮助。
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
3, xxx, 4"
print type(data)
"""
<type 'str'>
"""
print '
', np.genfromtxt(StringIO(data), delimiter=",", dtype="|S3", autostrip=True)
"""
[['1' 'abc' '2']
['3' 'xxx' '4']]
"""
print '
', type(data)
"""
<type 'str'>
"""
print '
', np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
"""
[[ 1. nan 2.]
[ 3. nan 4.]]
"""
蟒蛇3.5:
import numpy as np
from io import StringIO
import io
data = "1, abc , 2
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('
')
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('
')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", autostrip=True))
"""
[[ 1. nan 2.]
[ 3. nan 4.]]
"""
补充一下:
dtype="|Sx",其中 x = { 1, 2, 3, ...} 中的任意一个:
数据类型。Python 中 S1 和 S2 的区别
“|S1 和 |S2 字符串是数据类型描述符;第一个表示数组保存长度为 1 的字符串,第二个表示长度为 2。...”
解决方案 6:
您可以使用六个模块中的StringIO:
import six
import numpy
x = "1 3
4.5 8"
numpy.genfromtxt(six.StringIO(x))
解决方案 7:
为了使此处的示例
适用于 Python 3.5.2,您可以按如下方式重写:
import io
data =io.BytesIO(b"1, 2, 3
4, 5, 6")
import numpy
numpy.genfromtxt(data, delimiter=",")
更改的原因可能是文件的内容是数据(字节),只有通过某种方式解码后才能形成文本。genfrombytes
可能比 更好genfromtxt
。
解决方案 8:
这是Python 3的另一个示例。它将使用两个函数将两个数字相加,然后使用 CProfile 保存文件。然后它将使用StringIO
`.prof加载保存的文件,将数据转换为字符串以供进一步使用。
pstats.Stats`
主程序
import cProfile
import time
import pstats
from io import StringIO
def add_slow(a, b):
time.sleep(0.5)
return a+b
def add_fast(a, b):
return a+b
prof = cProfile.Profile()
def main_func():
arr = []
prof.enable()
for i in range(10):
if i%2==0:
arr.append(add_slow(i,i))
else:
arr.append(add_fast(i,i))
prof.disable()
#prof.print_stats(sort='time')
prof.dump_stats("main_funcs.prof")
return arr
main_func()
stream = StringIO();
stats = pstats.Stats("main_funcs.prof", stream=stream);
stats.print_stats()
stream.seek(0)
print(16*'=',"RESULTS",16*'=')
print (stream.read())
用法:
python3 main.py
输出:
================ RESULTS ================
Tue Jul 6 17:36:21 2021 main_funcs.prof
26 function calls in 2.507 seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno(function)
10 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}
5 2.507 0.501 2.507 0.501 {built-in method time.sleep}
5 0.000 0.000 2.507 0.501 profiler.py:39(add_slow)
5 0.000 0.000 0.000 0.000 profiler.py:43(add_fast)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
注释:我们可以观察到,在上面的代码中,time.sleep 函数大约需要 2.507 秒。
解决方案 9:
我希望这能满足你的要求
import PyPDF4
import io
pdfFile = open(r'test.pdf', 'rb')
pdfReader = PyPDF4.PdfFileReader(pdfFile)
pageObj = pdfReader.getPage(1)
pagetext = pageObj.extractText()
for line in io.StringIO(pagetext):
print(line)