pandas не удается прочитать из большого объекта StringIO

Я использую pandas для управления большим массивом 8-байтовых целых чисел. Эти целые числа включаются в качестве разделенных пробелами элементов столбца в CSV-файл с разделителями-запятыми, а размер массива составляет около 10000x10000.

Pandas может быстро читать данные с разделителями-запятыми из первых нескольких столбцов в качестве фрейма данных, а также быстро хранить строки с разделителями-пробелами в другом фрейме данных с минимальными хлопотами. Беда приходит, когда я пытаюсь бросить, превратить стол из одного столбец строк, разделенных пробелами, для фрейма данных из 8-разрядных целых чисел.

я попробовал следующее:

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

но использование памяти невыносимо-10 МБ целых чисел потребляет 2 ГБ памяти. Мне сказали, что это ограничение языка, и я ничего не могу с этим поделать.

в качестве возможного обходного пути мне посоветовали сохранить строковые данные в CSV-файл, а затем перезагрузить CSV-файл как фрейм данных целых чисел с пробелами. Это хорошо работает, но чтобы избежать замедления записи на диск, я попытался написать объект 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 не является проблемой.

возможно, что мне нужно заменить c С c.getvalue() в строке read_csv, но когда я это делаю, интерпретатор пытается распечатать содержимое c в терминале! Конечно, есть способ обойти это.

заранее спасибо за помощь.

1 ответов


здесь есть два вопроса, один фундаментальный и один, с которым вы просто еще не сталкивались. :^)

во-первых, после того, как вы напишите c, вы находитесь в конце (виртуального) файла. Вам нужно seek вернуться к началу. В качестве примера мы будем использовать меньшую сетку:

>>> 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

который генерирует ошибку" нет столбцов". Если мы ... --4--> во-первых, хотя:

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

но теперь вы заметите второй вопрос -- запятые? Я думал, нам нужно место. разделители? Но!--6--> только sep, а не delimiter. Мне кажется, он должен либо принять это, либо возразить, что это не так, но молча игнорировать это похоже на ошибку. Во всяком случае, если мы используем 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