Utilisation du format Parquet sur le CASD
Conversion de POTE en parquet
Pandas peut lire le sas7bdat mais pas le fichier POTE d'un coup, donc nous avons deux options :
- Lire le fichier complet par petit morceaux (chunk) et les sauver au fur et à mesure en parquet.
- Lire les colonnes une par une et les enregistrer dans un parquet par colonne.
Nous avons essayé de regrouper ces parquets entre eux mais il y a un problème de mémoire :
- En utilisant pyarrow et la méthode https://arrow.apache.org/docs/python/generated/pyarrow.Table.html#pyarrow.Table.append_column , même en ajoutant les colonnes une par une la mémoire sature quand les données dépassent 40Go, qui est la taille de la mémoire paginée sur le disque.
Notes sur parquet
Parquet stocke les données en colonne mais utilise une notion de group de ligne (row group, aussi appelé block-size) pour retrouver plus vite les données.
Ces row groups devraient être des blocs de 512 Mo à 1Go.
Dans Pandas, il y a un paramètre row_group_size
pour le définir :
df.to_parquet("my_file.parquet", row_group_size=1000, engine="pyarrow")
D'après https://arrow.apache.org/docs/python/generated/pyarrow.parquet.write_table.html la valeur par défaut est 1024 * 1024, soit 1 048 576 lignes par groupe.
Or, sur le CASD nous en avons seulement 130 000.
Obtenir des informations sur un fichier parquet
Il y a un outil en ligne de commande : pqrs
Avec Python nous pouvons avoir des informations avec le code suivant :
import pyarrow.parquet as pq
# Open the Parquet file
file = pq.ParquetFile('...../person-0.parquet')
# Get the metadata of the file
metadata = file.metadata
# Get the number of row groups
num_row_groups = metadata.num_row_groups
# Print the number of row groups
print(f'Number of row groups: {num_row_groups}')
to_batches
d'une Table pyarrow
Gestion de la taille des chunks dans PyArrow semble gérer lui même la taille des chunks qu'il fait dans cette fonction. On peut uniquement paramétrer max_chunksize
mais ça n'oblige pas la taille du chunk.
La question est comment cette optimisation est elle faite ?
Série de tests réalisés le 10/01/24 sur le CASD avec 1 table foyer fiscal et des chunks de table individus en input :
-
Test 1 : batch de taille 500 000:
- Pour toutes les itérations il prend 131 072 foyers fiscaux qu'il va chercher dans les tables individus
- Pour certaines itérations il ne trouve pas l'ensemble des 131 072 dans les tables individus voire pour plusieurs itérations aucun n'est trouvé --> A priori problème réglé, cela venait des tables individus
- La simulation c'est arrêté au bout de 2h env. à l'itération 22 (i=21) du fait de la saturation de la mémoire
--> ajout d'un
del survey_scenario
etgc.collect()
à la fin de la boucle, à voir si ça marche
-
Test 2 : batch de taille 1 000 000, testé uniquement pour les 2 premières itérations
- 131 072 foyers fiscaux sont sélectionnés, vu les résultats a priori bien les mêmes que le test précédent
-
Test 3 : batch de 100 000, testé sur 6 itérations:
- Une itération sur deux il prend 100 000 foyers fiscaux et pour l'autre itération sur 2 il en prend 31 072.