HDFStore:table.select和RAM的使用(HDFStore: table.selec

2019-08-20 15:56发布

我试图从大约1 GB的HDFStore表中选择任意行。 RAM使用爆炸时,我问大约50个随机行。

我使用熊猫0-11-dev, python 2.7, linux64

在第一种情况下的内存使用适合的大小chunk

with pd.get_store("train.h5",'r') as train:
for chunk in train.select('train',chunksize=50):
    pass

在第二种情况下,它似乎是整个表加载到RAM

r=random.choice(400000,size=40,replace=False)
train.select('train',pd.Term("index",r))

在后一种情况下,内存使用符合等价chunk大小

r=random.choice(400000,size=30,replace=False)    
train.select('train',pd.Term("index",r))

我百思不得其解,为什么从30到40的随机行动诱导RAM的使用这样的急剧增加。

注意表中已被索引创建这样当该索引=范围(NROWS(表)),使用以下代码:

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

感谢您的见解

编辑来回答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})

作为应用

txtfile2hdfstore('Train.csv','train.h5','train',sep=',')

Answer 1:

这是一个已知的问题,看到这里的参考: https://github.com/pydata/pandas/pull/2755

本质上,查询被变成numexpr评价表达。 存在如下情况:我无法通过很多的问题or条件numexpr(其取决于所产生的表达的总长度上)。

所以,我只是限制我们传递给numexpr表达。 如果它超过一定数目的or条件,则查询完成作为一个过滤器,而不是一个内核选择。 基本上,这意味着表被读取,然后重新索引。

这是我的增强功能列表: https://github.com/pydata/pandas/issues/2391 (17)。

作为一种变通方法,只是分裂您查询成多者和CONCAT结果。 要快很多,而且使用的内存一定量



文章来源: HDFStore: table.select and RAM usage