2016-06-25 11 views
3

Ich versuche, eine HDF-Datei von 64 GB (komprimiert mit Blosc) mit der Pandas-Bibliothek zu lesen. Der Dataframe enthält 3 Spalten und 11410996915 Zeilen. Ich versuche, konkrete Zeilen nach Index mit der Methode pandas.read_hdf und dem Argument wo auszuwählen. Das Problem ist, dass manchmal muß ich Tausende von Zeilen erhalten, so in meiner wo Parameter mir etwas so:pandas read_hdf mit großen Bedingungen

simMat = pd.read_hdf('global.h5','matrix', columns=['similarity'], where='index in {}'.format(listIdx)) 

wo listIdx ist eine Liste von integer, die die Indizes repräsentieren ich zurück bekommen möge. Wenn diese Liste mehr als 31 Elemente enthält, erhalte ich einen Speicherfehler. Ich fing an, in den Code der pandas-Bibliothek zu schauen und entdeckte, dass in der Datei pytables.py in der Klasse BinOp eine Variable namens _max_selectors steht, die den Wert 31 zugewiesen hat. Diese Variable wird danach in diesem Code verwendet:

# if too many values to create the expression, use a filter instead 
if self.op in ['==', '!='] and len(values) > self._max_selectors: 

    filter_op = self.generate_filter_op() 
    self.filter = (
     self.lhs, 
     filter_op, 
     pd.Index([v.value for v in values])) 
    return self 

Die Verwendung eines Filters bewirkt, dass die Bibliothek versucht, den gesamten Datenrahmen zu laden, und dadurch entsteht der MemoryError. Ich habe versucht, auch den Chunksize-Parameter mit einem Wert von 10 zu verwenden, und es hat auch nicht funktioniert. Kennen Sie eine bessere Möglichkeit, eine HDF-Datei mit so vielen Indizes abzufragen?

Antwort

1

können Sie die folgende Technik verwenden:

pd.read_hdf(filename, 'key', where='index = vals') 

wo vals ist pd.Series oder ein Python list Variable

Sie können auch Spalten verwenden, um andere DF zum Filtern gehören,:

In [201]: another_df = pd.DataFrame(np.random.randint(0, 100, size=(100, 3)), columns=list('abc')) 

In [202]: pd.read_hdf(fn, 'test', where='a = another_df["a"]').shape 
Out[202]: (573, 3) 

oder ein anderer DF-Index:

In [203]: pd.read_hdf(fn, 'test', where='index = another_df.index').shape 
Out[203]: (100, 3) 

Demo:

Setup

fn = r'D:\temp\.data\hdf\test.h5' 

store = pd.HDFStore(fn) 

df = pd.DataFrame(np.random.randint(0, 10**4, size=(10**5, 3)), columns=list('abc')) 

store.append('test', df, data_columns=True, complib='blosc', complevel=5) 

store.close() 

-Test

vals = pd.Series(np.random.randint(0, 100, 500)) 

In [196]: pd.read_hdf(fn, 'test', where='index = vals').shape 
Out[196]: (98, 3) 

Same mit einer Python-Liste:

idx_list = vals.tolist() 

In [197]: pd.read_hdf(fn, 'test', where='index = idx_list').shape 
Out[197]: (98, 3)