use*_*375 6 python pytables pandas hdfstore
我试图从大约1 GB的HDFStore表中选择随机行.当我要求大约50个随机行时,RAM使用率会爆炸.
我正在使用熊猫0-11-dev, python 2.7, linux64.
在第一种情况下,RAM使用量适合大小 chunk
with pd.get_store("train.h5",'r') as train:
for chunk in train.select('train',chunksize=50):
pass
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,似乎整个表都被加载到RAM中
r=random.choice(400000,size=40,replace=False)
train.select('train',pd.Term("index",r))
Run Code Online (Sandbox Code Playgroud)
在最后一种情况下,RAM使用量与等效chunk大小相符
r=random.choice(400000,size=30,replace=False)
train.select('train',pd.Term("index",r))
Run Code Online (Sandbox Code Playgroud)
我很困惑,为什么从30行随机移动到40行会导致RAM使用率急剧增加.
请注意,使用以下代码创建索引= range(nrows(table))时,表已被编入索引:
def txtfile2hdfstore(infile, storefile, table_name, sep="\t", header=0, chunksize=50000 ):
max_len, dtypes0 = txtfile2dtypes(infile, sep, header, chunksize)
with pd.get_store( storefile,'w') as store:
for i, chunk in enumerate(pd.read_table(infile,header=header,sep=sep,chunksize=chunksize, dtype=dict(dtypes0))):
chunk.index= range( chunksize*(i), chunksize*(i+1))[:chunk.shape[0]]
store.append(table_name,chunk, min_itemsize={'values':max_len})
Run Code Online (Sandbox Code Playgroud)
感谢您的见解
编辑回答Zelazny7
这是我用来编写Train.csv到train.h5的文件.我用Zelazny7的代码编写了这个代码来自如何解决HDFStore异常:无法找到正确的原子类型
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
def object_max_len(x):
if x.dtype != 'object':
return
else:
return len(max(x.fillna(''), key=lambda x: len(str(x))))
def txtfile2dtypes(infile, sep="\t", header=0, chunksize=50000 ):
max_len = pd.read_table(infile,header=header, sep=sep,nrows=5).apply( object_max_len).max()
dtypes0 = pd.read_table(infile,header=header, sep=sep,nrows=5).dtypes
for chunk in pd.read_table(infile,header=header, sep=sep, chunksize=chunksize):
max_len = max((pd.DataFrame(chunk.apply( object_max_len)).max(),max_len))
for i,k in enumerate(zip( dtypes0[:], chunk.dtypes)):
if (k[0] != k[1]) and (k[1] == 'object'):
dtypes0[i] = k[1]
#as of pandas-0.11 nan requires a float64 dtype
dtypes0.values[dtypes0 == np.int64] = np.dtype('float64')
return max_len, dtypes0
def txtfile2hdfstore(infile, storefile, table_name, sep="\t", header=0, chunksize=50000 ):
max_len, dtypes0 = txtfile2dtypes(infile, sep, header, chunksize)
with pd.get_store( storefile,'w') as store:
for i, chunk in enumerate(pd.read_table(infile,header=header,sep=sep,chunksize=chunksize, dtype=dict(dtypes0))):
chunk.index= range( chunksize*(i), chunksize*(i+1))[:chunk.shape[0]]
store.append(table_name,chunk, min_itemsize={'values':max_len})
Run Code Online (Sandbox Code Playgroud)
应用为
txtfile2hdfstore('Train.csv','train.h5','train',sep=',')
Run Code Online (Sandbox Code Playgroud)
这是一个已知问题,请参阅此处的参考:https://github.com/pydata/pandas/pull/2755
本质上,查询被转换为numexpr用于评估的表达式.有一个问题我无法将很多or条件传递给numexpr(它取决于生成的表达式的总长度).
所以我只是限制了传递给numexpr的表达式.如果它超过一定数量的or条件,那么查询将作为过滤器完成,而不是内核内选择.基本上这意味着读取表然后重新编制索引.
这是在我的增强列表中:https://github.com/pydata/pandas/issues/2391(17).
作为一种解决方法,只需将您的查询分成多个查询并连接结果即可.应该快得多,并使用恒定的内存量
| 归档时间: |
|
| 查看次数: |
1448 次 |
| 最近记录: |