2017-02-03 6 views
3

J'ai une dataframe de 2 Go qui est une écriture une fois, lire beaucoup df. Je voudrais utiliser le df dans les pandas, donc j'utilisais df.read_hdf et df.to_hdf dans un format fixe qui fonctionne très bien en lecture et en écriture.Lecture rapide des colonnes spécifiées en df en utilisant pandas.to_hdf

Cependant, le df est en train de croître avec l'ajout de colonnes, donc je voudrais utiliser le format de la table à la place, donc je peux sélectionner les colonnes dont j'ai besoin pour lire les données. Je pensais que cela me donnerait un avantage de vitesse, mais de tester cela ne semble pas être le cas.

Cet exemple:

import numpy as np 
import pandas as pd 
df = pd.DataFrame(np.random.randn(10000000,9),columns=list('ABCDEFGHI')) 
%time df.to_hdf("temp.h5", "temp", format ="fixed", mode="w") 
%time df.to_hdf("temp2.h5", "temp2", format="table", mode="w") 

montre format fixe est légèrement plus rapide (6.8s vs 5,9 secondes sur ma machine).

lire ensuite les données (après une petite pause pour faire le fichier que a été entièrement enregistrée):

%time x = pd.read_hdf("temp.h5", "temp") 
%time y = pd.read_hdf("temp2.h5", "temp2") 
%time z = pd.read_hdf("temp2.h5", "temp2", columns=list("ABC")) 

Rendement:

Wall time: 420 ms (fixed) 
Wall time: 557 ms (format) 
Wall time: 671 ms (format, specified columns) 

Je comprends le format fixe est plus rapide en lire les données, mais pourquoi la df est-elle avec des colonnes spécifiées plus lent que de lire l'intégralité des données? Quel est l'avantage d'utiliser la mise en forme de la table (avec ou sans colonnes spécifiées) sur un formatage fixe?

Y a-t-il un avantage de mémoire quand le df devient encore plus grand?

Répondre

3

IMO le principal avantage de l'utilisation de format='table' en conjonction avec data_columns=[list_of_indexed_columns] est la possibilité de lire conditionnellement (voir le paramètre where="where clause") d'énormes fichiers HDF5. Alors que vous pouvez filtrer vos données tout en lisant et traiter vos données en morceaux pour éviter MemoryError.

Vous pouvez essayer d'enregistrer des colonnes simples ou des groupes de colonnes (ceux qui seront lus la plupart du temps) dans différents fichiers HDF ou dans le même fichier avec des clés différentes.

Je voudrais aussi envisager d'utiliser la technologie "de pointe" - Feather-Format

Tests et calendrier:

import feather 

écriture sur le disque en trois formats: (HDF5 fixe, HDF% table, plume)

df = pd.DataFrame(np.random.randn(10000000,9),columns=list('ABCDEFGHI')) 
df.to_hdf('c:/temp/fixed.h5', 'temp', format='f', mode='w') 
df.to_hdf('c:/temp/tab.h5', 'temp', format='t', mode='w') 
feather.write_dataframe(df, 'c:/temp/df.feather') 

lecture à partir du disque:

In [122]: %timeit pd.read_hdf(r'C:\Temp\fixed.h5', "temp") 
1 loop, best of 3: 409 ms per loop 

In [123]: %timeit pd.read_hdf(r'C:\Temp\tab.h5', "temp") 
1 loop, best of 3: 558 ms per loop 

In [124]: %timeit pd.read_hdf(r'C:\Temp\tab.h5', "temp", columns=list('BDF')) 
The slowest run took 4.60 times longer than the fastest. This could mean that an intermediate result is being cached. 
1 loop, best of 3: 689 ms per loop 

In [125]: %timeit feather.read_dataframe('c:/temp/df.feather') 
The slowest run took 6.92 times longer than the fastest. This could mean that an intermediate result is being cached. 
1 loop, best of 3: 644 ms per loop 

In [126]: %timeit feather.read_dataframe('c:/temp/df.feather', columns=list('BDF')) 
1 loop, best of 3: 218 ms per loop # WINNER !!! 

PS si vous rencontrez l'erreur suivante lors de l'utilisation feather.write_dataframe(...):

FeatherError: Invalid: no support for strided data yet 

ici est une solution de contournement:

df = df.copy() 

après feather.write_dataframe(df, path) devrait fonctionner correctement ...

+0

Merci. Pourriez-vous élaborer sur la façon de sauvegarder les données transposées? Cela signifie-t-il que je devrais enregistrer des colonnes avec des clés séparées, mais dans le même fichier hdf? Pourriez-vous peut-être donner un exemple? – user6538642

+0

@ user6538642, quel est votre "habituel" env. DF forme? – MaxU

+1

shape = (6mln * 50), nombre de colonnes augmentant jusqu'à quelques centaines. L'index est un multi-index (date (au format datetime) et nom) – user6538642