cas*_*avo 9 python csv stringio pandas cstringio
我正在使用pandas来管理大量的8字节整数.这些整数作为空格分隔的元素包含在逗号分隔的CSV文件中,并且数组大小约为10000x10000.
Pandas能够快速读取前几列中逗号分隔的数据作为DataFrame,并且还可以轻松地将空格分隔的字符串存储在另一个DataFrame中.当我尝试将表从一列空格分隔的字符串转换为8位整数的DataFrame时,就会遇到麻烦.
我尝试过以下方法:
intdata = pd.DataFrame(strdata.columnname.str.split().tolist(), dtype='uint8')
Run Code Online (Sandbox Code Playgroud)
但内存使用情况令人难以忍受 - 价值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')
Run Code Online (Sandbox Code Playgroud)
这会产生以下错误消息:
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
Run Code Online (Sandbox Code Playgroud)
这是令人费解的,因为如果我运行完全相同的代码'c.csv'代替c,代码完美地工作.另外,如果我使用以下代码段:
file = open('c.csv', 'w')
file.write(c.getvalue())
Run Code Online (Sandbox Code Playgroud)
保存CSV文件没有任何问题,因此写入StringIO对象不是问题.
这可能是我需要更换c与c.getvalue()在read_csv线,但是当我这样做,解释试图打印的内容c在终端!当然有办法解决这个问题.
在此先感谢您的帮助.
DSM*_*DSM 15
这里有两个问题,一个基本问题,一个你还没有遇到的问题.:^)
首先,在您写入之后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
Run Code Online (Sandbox Code Playgroud)
这会产生"无列"错误.如果我们seek第一个,但是:
>>> c.seek(0)
>>> next(c)
'103,3,171,239,150,35,224,190,225,57\n'
Run Code Online (Sandbox Code Playgroud)
但现在你会注意到第二个问题 - 逗号?我以为我们要求空间分隔符?但to_csv只接受sep,而不是delimiter.在我看来它应该接受它或反对它没有,但默默地忽略它感觉就像一个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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5191 次 |
| 最近记录: |