python – pandas无法从大型StringIO对象中读取

我正在使用pandas来管理大量的8字节整数.这些整数包含在以逗号分隔的CSV文件中的列的空格分隔元素中,并且数组大小约为10000×10000.

Pandas能够快速读取前几列中逗号分隔的数据作为DataFrame,并且还可以轻松地将空格分隔的字符串存储在另一个DataFrame中.当我尝试将表从空格分隔的字符串列转换为8位整数的DataFrame时,就会遇到麻烦.

我尝试过以下方法:

intdata = pd.DataFrame(strdata.columnname.str.split().tolist(), dtype='uint8')

但内存使用情况令人难以忍受 – 价值10MB的整数消耗2GB内存.我被告知这是语言的限制,在这种情况下我无能为力.

作为一种可能的解决方法,我被建议将字符串数据保存为CSV文件,然后将CSV文件重新加载为以空格分隔的整数的DataFrame.这很好用,但为了避免写入磁盘的速度减慢,我尝试写一个StringIO对象.

这是一个最小的非工作示例:

import numpy as np
import pandas as pd
from cStringIO import StringIO

a = np.random.randint(0,256,(10000,10000)).astype('uint8')
b = pd.DataFrame(a)
c = StringIO()
b.to_csv(c, delimiter=' ', header=False, index=False)
d = pd.io.parsers.read_csv(c, delimiter=' ', header=None, dtype='uint8')

这会产生以下错误消息:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/site-packages/pandas/io/parsers.py", line 443, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "/usr/lib64/python2.7/site-packages/pandas/io/parsers.py", line 228, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
  File "/usr/lib64/python2.7/site-packages/pandas/io/parsers.py", line 533, in __init__
    self._make_engine(self.engine)
  File "/usr/lib64/python2.7/site-packages/pandas/io/parsers.py", line 670, in _make_engine
    self._engine = CParserWrapper(self.f, **self.options)
  File "/usr/lib64/python2.7/site-packages/pandas/io/parsers.py", line 1032, in __init__
    self._reader = _parser.TextReader(src, **kwds)
  File "parser.pyx", line 486, in pandas.parser.TextReader.__cinit__ (pandas/parser.c:4494)
ValueError: No columns to parse from file

这令人费解,因为如果我用’c.csv’而不是c运行完全相同的代码,代码就能完美运行.另外,如果我使用以下代码段:

file = open('c.csv', 'w')
file.write(c.getvalue())

保存CSV文件没有任何问题,因此写入StringIO对象不是问题.

我可能需要在read_csv行中用c.getvalue()替换c,但是当我这样做时,解释器会尝试在终端中打印c的内容!当然有办法解决这个问题.

在此先感谢您的帮助.

这里有两个问题,一个基本问题,一个你还没有遇到的问题. :^)

首先,在写入c之后,您就在(虚拟)文件的末尾.你需要回到起点.我们将使用较小的网格作为示例:

>>> a = np.random.randint(0,256,(10,10)).astype('uint8')
>>> b = pd.DataFrame(a)
>>> c = StringIO()
>>> b.to_csv(c, delimiter=' ', header=False, index=False)
>>> next(c)
Traceback (most recent call last):
  File "<ipython-input-57-73b012f9653f>", line 1, in <module>
    next(c)
StopIteration

这会产生“无列”错误.如果我们先寻求,但是:

>>> c.seek(0)
>>> next(c)
'103,3,171,239,150,35,224,190,225,57\n'

但现在你会注意到第二个问题 – 逗号?我以为我们要求空间分隔符?但to_csv只接受sep,而不是分隔符.在我看来它应该接受它或反对它不会,但默默地忽略它感觉就像一个bug.无论如何,如果我们使用sep(或delim_whitespace = True):

>>> a = np.random.randint(0,256,(10,10)).astype('uint8')
>>> b = pd.DataFrame(a)
>>> c = StringIO()
>>> b.to_csv(c, sep=' ', header=False, index=False)
>>> c.seek(0)
>>> d = pd.read_csv(c, sep=' ', header=None, dtype='uint8')
>>> d
     0    1    2    3    4    5    6    7    8    9
0  209   65  218  242  178  213  187   63  137  145
1  161  222   50   92  157   31   49   62  218   30
2  182  255  146  249  115   91  160   53  200  252
3  192  116   87   85  164   46  192  228  104  113
4   89  137  142  188  183  199  106  128  110    1
5  208  140  116   50   66  208  116   72  158  169
6   50  221   82  235   16   31  222    9   95  111
7   88   36  204   96  186  205  210  223   22  235
8  136  221   98  191   31  174   83  208  226  150
9   62   93  168  181   26  128  116   92   68  153
翻译自:https://stackoverflow.com/questions/24562869/pandas-unable-to-read-from-large-stringio-object

转载注明原文:python – pandas无法从大型StringIO对象中读取