J'essaie de charger un gros fichier (2 Go) rempli de chaînes JSON, délimité par des retours à la ligne. Ex:
{
"key11": value11,
"key12": value12,
}
{
"key21": value21,
"key22": value22,
}
…
La façon dont je l'importe maintenant est:
content = open(file_path, "r").read()
j_content = json.loads("[" + content.replace("}\n{", "},\n{") + "]")
Ce qui semble être un hack (ajouter des virgules entre chaque chaîne JSON et également un crochet carré de début et de fin pour en faire une liste appropriée).
Existe-t-il une meilleure façon de spécifier le délimiteur JSON (newline \n
au lieu d'une virgule ,
)?
De plus, Python
ne semble pas allouer correctement la mémoire pour un objet construit à partir de 2 Go de données, existe-t-il un moyen de construire chaque JSON
objet pendant que je lis le fichier ligne par ligne? Merci!
Il suffit de lire chaque ligne et de construire un objet json à ce moment:
with open(file_path) as f:
for line in f:
j_content = json.loads(line)
De cette façon, vous chargez un objet json complet approprié (à condition qu'il n'y ait pas de \n
dans une valeur json quelque part ou au milieu de votre objet json) et vous évitez les problèmes de mémoire car chaque objet est créé en cas de besoin.
Il y a aussi cette réponse:
contents = open(file_path, "r").read()
data = [json.loads(str(item)) for item in contents.strip().split('\n')]
Cela fonctionnera pour le format de fichier spécifique que vous avez donné. Si votre format change, vous devrez modifier la façon dont les lignes sont analysées.
{
"key11": 11,
"key12": 12
}
{
"key21": 21,
"key22": 22
}
Il suffit de lire ligne par ligne et de construire les blocs JSON au fur et à mesure:
with open(args.infile, 'r') as infile:
# Variable for building our JSON block
json_block = []
for line in infile:
# Add the line to our JSON block
json_block.append(line)
# Check whether we closed our JSON block
if line.startswith('}'):
# Do something with the JSON dictionary
json_dict = json.loads(''.join(json_block))
print(json_dict)
# Start a new block
json_block = []
Si vous souhaitez analyser un fichier JSON très volumineux sans tout enregistrer en mémoire, vous devez envisager d'utiliser les méthodes de rappel object_hook ou object_pairs_hook dans l'API json.load.
Il suffit de le lire ligne par ligne et d'analyser e à travers un flux pendant que votre astuce de piratage (en ajoutant des virgules entre chaque chaîne JSON et également un crochet carré de début et de fin pour en faire une liste appropriée) n'est pas compatible avec la mémoire si le fichier est trop plus de 1 Go car tout le contenu atterrira sur la RAM.