J'essaie actuellement d'ouvrir un fichier contenant des pandas et du python à des fins d'apprentissage automatique. Il serait idéal pour moi de les avoir tous dans un DataFrame. Maintenant, le fichier fait 18 Go et ma mémoire vive de 32 Go, mais je continue à avoir des erreurs de mémoire.
D'après votre expérience, est-ce possible? Si non, connaissez-vous une meilleure façon de contourner cela? (table de ruche? augmenter la taille de ma RAM à 64? créer une base de données et y accéder depuis python)
pandas
, vous devez disposer de 5 à 10 fois plus de RAM. Je recommande de faire desinplace
opérations, appeler explicitementgarbage.collector
pour désallouer des objets.Réponses:
S'il s'agit d'un fichier csv et que vous n'avez pas besoin d'accéder à toutes les données en même temps lors de la formation de votre algorithme, vous pouvez le lire en morceaux. La
pandas.read_csv
méthode vous permet de lire un fichier par morceaux comme ceci:Voici la documentation de la méthode
la source
Il existe deux possibilités: soit vous devez avoir toutes vos données en mémoire pour le traitement (votre algorithme d’apprentissage automatique souhaite par exemple les consommer toutes en même temps), soit vous pouvez vous en passer (votre algorithme n’a par exemple besoin que d’échantillons de lignes). colonnes à la fois).
Dans le premier cas, vous devrez résoudre un problème de mémoire . Augmentez la taille de votre mémoire, louez une machine dans le cloud, utilisez des opérations in-situ, fournissez des informations sur le type de données que vous lisez, assurez-vous de supprimer toutes les variables inutilisées et de ramasser les déchets, etc.
Il est très probable que 32 Go de RAM ne suffiraient pas à Pandas pour gérer vos données. Notez que le nombre entier "1" est juste un octet lorsqu'il est stocké en tant que texte mais 8 octets lorsqu'il est représenté par
int64
(ce qui est la valeur par défaut lorsque Pandas le lit dans du texte). Vous pouvez faire le même exemple avec un nombre à virgule flottante "1.0" qui passe d'une chaîne de 3 octets à une chaîne de 8 octetsfloat64
par défaut. Vous gagnerez peut-être un peu d’espace en laissant les pandas savoir avec précision les types à utiliser pour chaque colonne et en forçant les représentations les plus petites possibles, mais nous n’avons même pas commencé à parler de la surcharge de la structure de données de Python ici, ce qui peut ajouter un ou deux pointeurs facilement ici et là. , et les pointeurs sont de 8 octets chacun sur un ordinateur 64 bits.Pour résumer: non, 32 Go de RAM ne sont probablement pas suffisants pour que les Pandas puissent gérer un fichier de 20 Go.
Dans le second cas (qui est plus réaliste et qui s’applique probablement à vous), vous devez résoudre un problème de gestion des données . En effet, le fait de charger toutes les données alors que vous n'en avez vraiment besoin que pour le traitement peut être le signe d'une mauvaise gestion des données. Il y a plusieurs options ici:
Utilisez une base de données SQL. Si vous le pouvez, c'est presque toujours le premier choix et une solution décente et confortable. 20 Go semble correspondre à la taille de la plupart des bases de données SQL, même sans ordinateur portable (haut de gamme). Vous pourrez indexer des colonnes, effectuer des agrégations de base via SQL et obtenir les sous-échantillons nécessaires dans des pandas pour un traitement plus complexe à l'aide d'un simple
pd.read_sql
. Déplacer les données vers une base de données vous donnera également l'occasion de réfléchir aux types de données et aux tailles réelles de vos colonnes.Si vos données sont principalement numériques (c.-à-d. Matrices ou tenseurs), vous pouvez envisager de les conserver au format HDF5 (voir PyTables ), ce qui vous permet de ne lire que les tranches de grandes matrices nécessaires sur le disque. Les bases numpy.save et numpy.load obtiennent le même effet en mappant en mémoire les baies sur le disque. Pour les SIG et les données raster associées, il existe des bases de données dédiées , qui peuvent ne pas se connecter aux pandas aussi directement que SQL, mais doivent également vous permettre d'effectuer des tranches et des requêtes de manière raisonnablement simple.
Les pandas ne prennent pas en charge un tel mappage mémoire "partiel" de HDF5 ou de matrices Numpy, à ma connaissance. Si vous voulez toujours une sorte de solution "pur-pandas", vous pouvez essayer de contourner le problème en "sharding": soit en stockant les colonnes de votre immense table séparément (par exemple dans des fichiers séparés ou dans des "tables" séparées d'un HDF5 unique). fichier) et en ne chargeant que ceux nécessaires à la demande, ou en stockant les morceaux de lignes séparément. Cependant, vous devrez alors implémenter la logique de chargement des morceaux nécessaires, réinventant ainsi les bicyclettes déjà implémentées dans la plupart des bases de données SQL. L'option 1 serait peut-être encore plus simple ici. Toutefois, si vos données sont au format CSV, vous pouvez les traiter en morceaux en spécifiant le
chunksize
paramètre topd.read_csv
.la source
Je viens d'avoir ce problème il y a quelques jours! Je ne suis pas sûr que cela vous aide dans votre cas particulier, car vous ne fournissez pas autant de détails, mais ma situation était de travailler hors ligne sur un jeu de données «volumineux». Les données ont été obtenues sous forme de fichiers CSV compressés à 20 Go à partir de compteurs d’énergie, ainsi que des données chronologiques à plusieurs secondes.
Fichier IO:
Créez un itérateur de bloc directement sur le fichier gzip (ne décompressez pas le fichier!)
Itérer sur les morceaux
À l'intérieur de la boucle de morceau, je filtre et ré-échantillonne à temps. Ce faisant, j'ai réduit la taille de 20 Go à quelques centaines de Mo HDF5 pour une exploration plus poussée des données hors connexion.
la source
D'après mon expérience, l'initialisation
read_csv()
avec le paramètre alow_memory=False
tendance à être utile lors de la lecture de fichiers volumineux. Je ne pense pas que vous ayez mentionné le type de fichier que vous lisez, alors je ne sais pas si cela est applicable à votre situation.la source
Si votre fichier est un fichier CSV, vous pouvez simplement le faire dans Chunk by Chunk. Vous pouvez simplement faire:
la source