【问题标题】:Reading ARFF from ZIP with zipfile and scipy.io.arff使用 zipfile 和 scipy.io.arff 从 ZIP 读取 ARFF
【发布时间】:2019-08-09 15:28:09
【问题描述】:

我想在 scikit-learn 中处理相当大的 ARFF 文件。这些文件位于 zip 存档中,我不想在处理之前将存档解压缩到文件夹中。因此,我使用 Python 3.6 的 zipfile 模块:

from zipfile import ZipFile
from scipy.io.arff import loadarff

archive = ZipFile( 'archive.zip', 'r' )
datafile = archive.open( 'datafile.arff' )
data = loadarff( datafile )
# …
datafile.close()
archive.close()

但是,这会产生以下错误:

Traceback (most recent call last):
  File "./m.py", line 6, in <module>
    data = loadarff( datafile )
  File "/usr/lib64/python3.6/site-packages/scipy/io/arff/arffread.py", line 541, in loadarff
    return _loadarff(ofile)
  File "/usr/lib64/python3.6/site-packages/scipy/io/arff/arffread.py", line 550, in _loadarff
    rel, attr = read_header(ofile)
  File "/usr/lib64/python3.6/site-packages/scipy/io/arff/arffread.py", line 323, in read_header
    while r_comment.match(i):
TypeError: cannot use a string pattern on a bytes-like object

根据loadarff documentationloadarff 需要一个类似文件的对象。 根据zipfile documentationopen返回一个类似文件的ZipExtFile

因此,我的问题是如何使用 ZipFile.open 返回的内容作为loadarff 的 ARFF 输入。

注意:如果我手动解压缩并使用data = loadarff( 'datafile.arff' ) 直接加载 ARFF,一切都很好。

【问题讨论】:

  • loadarff 需要一个类似文件的对象。所以你应该读入一个内存文件,比如 object.你能试试这个吗? in_mem_fo = StringIO(archive.read('datafile.arff'))
  • 这会产生错误:文件“m.py”,第 7 行,在 in_mem_fo = StringIO(archive.read('datafile.arff')) TypeError: initial_value must be str or None ,而不是字节
  • 但你的想法让我找到了解决方案:in_mem_fo = StringIO(archive.read('datafile.arff').decode("utf-8"))in_mem_fo = StringIO(archive.read('datafile.arff').decode("ascii"))
  • 太棒了。我添加了一个可能是更好的解决方案的答案。

标签: python scikit-learn scipy zipfile arff


【解决方案1】:
from io import BytesIO, TextIOWrapper
from zipfile import ZipFile
from scipy.io.arff import loadarff

zfile = ZipFile('archive.zip', 'r')
in_mem_fo = TextIOWrapper(BytesIO(zfile.read('datafile.arff')), encoding='utf-8')
data = loadarff(in_mem_fo)

zfile 读入内存中的BytesIO 对象。将TextIOWrapperencoding='utf-8' 一起使用。在loadarff 中使用这个内存缓冲文本对象。

编辑:结果zfile.open() 返回一个类似文件的对象,因此上述可以通过以下方式完成:

zfile = ZipFile('archive.zip', 'r')
in_mem_fo = TextIOWrapper(zfile.open('datafile.arff'), encoding='ascii')
data = loadarff(in_mem_fo)

感谢@Bernhard

【讨论】:

  • 再次感谢,您的回答启发了我另一种解决方案,我觉得它更优雅,因为它避免了先将所有内容放入内存:textfile = TextIOWrapper(datafile, encoding='ascii') 然后data = loadarff( textfile )。我建议您将这样的内容作为编辑添加到您的解决方案中,我接受这样其他人可以使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 2011-06-22
  • 2022-01-04
  • 2015-11-05
  • 1970-01-01
相关资源
最近更新 更多