Lors de la lecture d'un fichier HDF5 énorme avec "pandas.read_hdf ()", pourquoi ai-je encore MemoryError même si je lis en morceaux en spécifiant chunksize?
Description du problème:
J'utilise python pandas à lire un peu de gros fichier CSV et de les stocker dans HDF5, le fichier résultant HDF5 fichier est d'environ 10 GO.
Le problème se produit lors de la lecture en arrière. Même si j'ai essayé de le lire en morceaux, je reçois toujours MemoryError.
Voici Comment j'ai créer le HDF5 fichier:
import glob, os
import pandas as pd
hdf = pd.HDFStore('raw_sample_storage2.h5')
os.chdir("C:/RawDataCollection/raw_samples/PLB_Gate")
for filename in glob.glob("RD_*.txt"):
raw_df = pd.read_csv(filename,
sep=' ',
header=None,
names=['time', 'GW_time', 'node_id', 'X', 'Y', 'Z', 'status', 'seq', 'rssi', 'lqi'],
dtype={'GW_time': uint32, 'node_id': uint8, 'X': uint16, 'Y': uint16, 'Z':uint16, 'status': uint8, 'seq': uint8, 'rssi': int8, 'lqi': uint8},
parse_dates=['time'],
date_parser=dateparse,
chunksize=50000,
skip_blank_lines=True)
for chunk in raw_df:
hdf.append('raw_sample_all', chunk, format='table', data_columns = True, index = True, compression='blosc', complevel=9)
Voici Comment j'ai essayer de le lire en morceaux:
for df in pd.read_hdf('raw_sample_storage2.h5','raw_sample_all', chunksize=300000):
print(df.head(1))
Voici le message d'erreur que j'ai obtenu:
---------------------------------------------------------------------------
MemoryError Traceback (most recent call last)
<ipython-input-7-ef278566a16b> in <module>()
----> 1 for df in pd.read_hdf('raw_sample_storage2.h5','raw_sample_all', chunksize=300000):
2 print(df.head(1))
C:\Anaconda\lib\site-packages\pandas\io\pytables.pyc in read_hdf(path_or_buf, key, **kwargs)
321 store = HDFStore(path_or_buf, **kwargs)
322 try:
--> 323 return f(store, True)
324 except:
325
C:\Anaconda\lib\site-packages\pandas\io\pytables.pyc in <lambda>(store, auto_close)
303
304 f = lambda store, auto_close: store.select(
--> 305 key, auto_close=auto_close, **kwargs)
306
307 if isinstance(path_or_buf, string_types):
C:\Anaconda\lib\site-packages\pandas\io\pytables.pyc in select(self, key, where, start, stop, columns, iterator, chunksize, auto_close, **kwargs)
663 auto_close=auto_close)
664
--> 665 return it.get_result()
666
667 def select_as_coordinates(
C:\Anaconda\lib\site-packages\pandas\io\pytables.pyc in get_result(self, coordinates)
1346 "can only use an iterator or chunksize on a table")
1347
-> 1348 self.coordinates = self.s.read_coordinates(where=self.where)
1349
1350 return self
C:\Anaconda\lib\site-packages\pandas\io\pytables.pyc in read_coordinates(self, where, start, stop, **kwargs)
3545 self.selection = Selection(
3546 self, where=where, start=start, stop=stop, **kwargs)
-> 3547 coords = self.selection.select_coords()
3548 if self.selection.filter is not None:
3549 for field, op, filt in self.selection.filter.format():
C:\Anaconda\lib\site-packages\pandas\io\pytables.pyc in select_coords(self)
4507 return self.coordinates
4508
-> 4509 return np.arange(start, stop)
4510
4511 # utilities ###
MemoryError:
Mon environnement python:
INSTALLED VERSIONS
------------------
commit: None
python: 2.7.3.final.0
python-bits: 32
OS: Windows
OS-release: 7
machine: x86
processor: x86 Family 6 Model 42 Stepping 7, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
pandas: 0.15.2
nose: 1.3.4
Cython: 0.22
numpy: 1.9.2
scipy: 0.15.1
statsmodels: 0.6.1
IPython: 3.0.0
sphinx: 1.2.3
patsy: 0.3.0
dateutil: 2.4.1
pytz: 2015.2
bottleneck: None
tables: 3.1.1
numexpr: 2.3.1
matplotlib: 1.4.3
openpyxl: 1.8.5
xlrd: 0.9.3
xlwt: 0.7.5
xlsxwriter: 0.6.7
lxml: 3.4.2
bs4: 4.3.2
html5lib: None
httplib2: None
apiclient: None
rpy2: None
sqlalchemy: 0.9.9
pymysql: None
psycopg2: None
Edit 1:
Il a fallu environ une demi-heure pour le MemoryError à se produire après l'exécution de read_hdf(), et dans le même temps, j'ai vérifié taskmgr, et il y a peu d'activité du PROCESSEUR et de la mémoire totale utilisée n'a jamais dépassé 2.2 G. Il était environ 2,1 GO avant de m'exécuter le code. Donc, quel que soit pandas read_hdf() chargé dans la mémoire RAM est de moins de 100 MO (j'ai la 4G de RAM, et mon 32 bits-Windows système ne peut utiliser 2,7 G, et j'ai utilisé le reste pour disque RAM)
Voici le fichier hdf info:
In [2]:
hdf = pd.HDFStore('raw_sample_storage2.h5')
hdf
Out[2]:
<class 'pandas.io.pytables.HDFStore'>
File path: C:/RawDataCollection/raw_samples/PLB_Gate/raw_sample_storage2.h5
/raw_sample_all frame_table (typ->appendable,nrows->308581091,ncols->10,indexers->[index],dc->[time,GW_time,node_id,X,Y,Z,status,seq,rssi,lqi])
En outre, je peux lire une partie de l'hdf fichier en indiquant "start" et "stop" au lieu de "chunksize':
%%time
df = pd.read_hdf('raw_sample_storage2.h5','raw_sample_all', start=0,stop=300000)
print df.info()
print(df.head(5))
L'exécution a pris seulement 4 secondes, et la sortie est:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 300000 entries, 0 to 49999
Data columns (total 10 columns):
time 300000 non-null datetime64[ns]
GW_time 300000 non-null uint32
node_id 300000 non-null uint8
X 300000 non-null uint16
Y 300000 non-null uint16
Z 300000 non-null uint16
status 300000 non-null uint8
seq 300000 non-null uint8
rssi 300000 non-null int8
lqi 300000 non-null uint8
dtypes: datetime64[ns](1), int8(1), uint16(3), uint32(1), uint8(4)
memory usage: 8.9 MB
None
time GW_time node_id X Y Z status seq \
0 2013-10-22 17:20:58 39821761 3 20010 21716 22668 0 33
1 2013-10-22 17:20:58 39821824 4 19654 19647 19241 0 33
2 2013-10-22 17:20:58 39821888 1 16927 21438 22722 0 34
3 2013-10-22 17:20:58 39821952 2 17420 22882 20440 0 34
4 2013-10-22 17:20:58 39822017 3 20010 21716 22668 0 34
rssi lqi
0 -43 49
1 -72 47
2 -46 48
3 -57 46
4 -42 50
Wall time: 4.26 s
Remarquer 300000 lignes seulement pris de 8,9 MO de RAM, j'ai essayé d'utiliser chunksize avec start et stop:
for df in pd.read_hdf('raw_sample_storage2.h5','raw_sample_all', start=0,stop=300000,chunksize = 3000):
print df.info()
print(df.head(5))
Même MemoryError qui se passe.
Je ne comprends pas ce qui se passe ici, si le mécanisme interne en quelque sorte ignorer chunksize/start/stop et essayé de charger le tout dans la RAM, comment se fait-il n'y a presque aucune augmentation de l'utilisation de la RAM (seulement 100 MO) lorsque MemoryError qui se passe? Et pourquoi l'exécution de prendre une demi-heure juste pour arriver à l'erreur au tout début de la procédure, sans qu'ils remarquent d'utilisation de l'UC?
source d'informationauteur Ewan
Vous devez vous connecter pour publier un commentaire.
Si l'itérateur est construit principalement à traiter avec un
where
clause.PyTables
retourne une liste des indicies où la clause est Vrai. Ce sont les numéros de ligne. Dans ce cas, il n'y a pas de clause where, mais nous utilisons toujours l'indexeur, qui dans ce cas est simplementnp.arange
sur la liste des lignes.300MM lignes prend 2,2 GO. ce qui est beaucoup trop pour windows 32 bits (généralement plafonne autour de 1 GO). Sur 64 bits, ce ne serait pas un problème.
Donc cela devrait être géré par le découpage sémantique, ce qui ferait de ce prendre seulement une somme insignifiante de la mémoire. Problème ouvert ici.
Je vous suggère cette. Ici, l'indexation est calculée directement, ce qui permet d'itérateur sémantique.