Je me suis demandé... Si je lis, disons, un fichier csv de 400 Mo dans un dataframe pandas (en utilisant read_csv ou read_table), y a-t-il un moyen d'estimer la quantité de mémoire nécessaire ? J'essaie juste d'avoir une meilleure idée des cadres de données et de la mémoire...
Réponses
Trop de publicités?df.memory_usage()
retournera le nombre d'octets qu'occupe chaque colonne :
>>> df.memory_usage()
Row_ID 20906600
Household_ID 20906600
Vehicle 20906600
Calendar_Year 20906600
Model_Year 20906600
...
Pour inclure les index, passez index=True
.
Donc pour obtenir la consommation globale de mémoire :
>>> df.memory_usage(index=True).sum()
731731000
De plus, le fait de passer deep=True
permet d'obtenir un rapport d'utilisation de la mémoire plus précis, qui tient compte de l'utilisation complète des objets contenus.
En effet, l'utilisation de la mémoire ne comprend pas la mémoire consommée par les éléments qui ne sont pas des composants du tableau si deep=False
(cas par défaut).
Voici une comparaison des différentes méthodes - sys.getsizeof(df)
est le plus simple.
Pour cet exemple, df
est un cadre de données avec 814 lignes, 11 colonnes (2 ints, 9 objets) - lu à partir d'un shapefile de 427kb
sys.getsizeof(df)
\>>> import sys
>>> sys.getsizeof(df)
(gives results in bytes)
462456
df.memory_usage()
\>>> df.memory\_usage()
...
(lists each column at 8 bytes/row)
>>> df.memory\_usage().sum()
71712
(roughly rows \* cols \* 8 bytes)
>>> df.memory\_usage(deep=True)
(lists each column's full memory usage)
>>> df.memory\_usage(deep=True).sum()
(gives results in bytes)
462432
df.info()
Imprime les informations du cadre de données sur la sortie standard. Techniquement, il s'agit de kibibytes (KiB), et non de kilobytes - comme le dit la docstring, "L'utilisation de la mémoire est indiquée en unités lisibles par l'homme (représentation en base 2)". Pour obtenir des octets, il faut donc multiplier par 1024, par exemple 451,6 KiB = 462 438 octets.
\>>> df.info()
...
memory usage: 70.0+ KB
>>> df.info(memory\_usage='deep')
...
memory usage: 451.6 KB
J'ai pensé que je pourrais apporter quelques données supplémentaires à la discussion.
J'ai effectué une série de tests sur cette question.
En utilisant le programme python resource
J'ai obtenu l'utilisation de la mémoire de mon processus.
Et en écrivant le csv dans un StringIO
je pourrais facilement mesurer sa taille en octets.
J'ai réalisé deux expériences, chacune créant 20 cadres de données de tailles croissantes entre 10 000 lignes et 1 000 000 de lignes. Les deux ont 10 colonnes.
Dans la première expérience, je n'ai utilisé que des flottants dans mon jeu de données.
Voici comment la mémoire a augmenté par rapport au fichier csv en fonction du nombre de lignes. (Taille en mégaoctets)
Pour la deuxième expérience, j'ai utilisé la même approche, mais les données de l'ensemble de données ne comportaient que des chaînes courtes.
Il semble que la relation entre la taille du csv et la taille du dataframe peut varier considérablement, mais la taille en mémoire sera toujours supérieure d'un facteur 2-3 (pour les tailles de trame dans cette expérience).
J'adorerais compléter cette réponse avec d'autres expériences, veuillez commenter si vous voulez que j'essaie quelque chose de spécial.
Vous devez faire ça à l'envers.
In [4]: DataFrame(randn(1000000,20)).to_csv('test.csv')
In [5]: !ls -ltr test.csv
-rw-rw-r-- 1 users 399508276 Aug 6 16:55 test.csv
Techniquement, la mémoire c'est à peu près ceci (qui inclut les index)
In [16]: df.values.nbytes + df.index.nbytes + df.columns.nbytes
Out[16]: 168000160
Donc 168MB en mémoire avec un fichier de 400MB, 1M de lignes de 20 colonnes flottantes.
DataFrame(randn(1000000,20)).to_hdf('test.h5','df')
!ls -ltr test.h5
-rw-rw-r-- 1 users 168073944 Aug 6 16:57 test.h5
BEAUCOUP plus compact lorsqu'il est écrit comme un fichier HDF5 binaire.
In [12]: DataFrame(randn(1000000,20)).to_hdf('test.h5','df',complevel=9,complib='blosc')
In [13]: !ls -ltr test.h5
-rw-rw-r-- 1 users 154727012 Aug 6 16:58 test.h5
Les données étaient aléatoires, donc la compression ne sert pas à grand-chose.
Oui, c'est possible. Pandas stockera vos données dans un fichier numpy à deux dimensions. ndarray
en les regroupant par dtypes. ndarray
est en fait un tableau de données C brut avec un petit en-tête. Vous pouvez donc estimer sa taille en multipliant simplement la taille de la variable dtype
qu'il contient avec les dimensions du tableau.
Par exemple : si vous avez 1000 lignes avec 2 np.int32
et 5 np.float64
colonnes, votre DataFrame aura un 2x1000 np.int32
et un réseau 5x1000 np.float64
qui est :
4 octets*2*1000 + 8 octets*5*1000 = 48000 octets
- Réponses précédentes
- Plus de réponses