Преобразование JSON в CSV занимает очень много времени на большие файлы в Python - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь преобразовать очень большой файл json в csv. Код хорошо работает с небольшими файлами, но занимает много времени при выполнении того же кода на больших файлах. Сначала я протестировал его на файле размером 91 МБ, содержащем 80 000 записей, и потребовалосьоколо 45 минут, но после этого для больших файлов, содержащих 300 000 записей, это заняло около 5 часов.Есть ли способ сделать это с помощью мультиобработки?Я начинающий программист на Python, поэтому у меня нет идеи использовать многопроцессорность или многопоточность в Python.вот мой код

import json
import time
import pandas as pd

csv_project=pd.DataFrame([],columns=['abstract','authors','n_citation',"references","title","venue","year",'id'])


with open('test.json','r') as f:
    data = f.readlines()
j=0
for k,i in enumerate(data):

    if '{' in i and '}' in i:

        j+=1
        dictionary=json.loads(i)
        csv_project=csv_project.append(dictionary,ignore_index=True)
    else:
        pass 
    if j == 10000:
        print(str(k)+'number of entries done')
        csv_project.to_csv('data.csv')
        j=0
csv_project.to_csv('data.csv') 

Любая полезная помощь будет оценена.отредактируйте здесь образец формата JSON.

    {"abstract": "AdaBoost algorithm based on Haar-like features can achieves high accuracy (above 95%) in object detection.", 
"authors": ["Zheng Xu", "Runbin Shi", "Zhihao Sun", "Yaqi Li", "Yuanjia Zhao", "Chenjian Wu"], 
"n_citation": 0,
 "references": ["0a11984c-ab6e-4b75-9291-e1b700c98d52", "1f4152a3-481f-4adf-a29a-2193a3d4303c", "3c2ddf0a-237b-4d17-8083-c90df5f3514b", "522ce553-29ea-4e0b-9ad3-0ed4eb9de065", "579e5f24-5b13-4e92-b255-0c46d066e306", "5d0b987d-eed9-42ce-9bf3-734d98824f1b", "80656b4d-b24c-4d92-8753-bdb965bcd50a", "d6e37fb1-5f7e-448e-847b-7d1f1271c574"],
 "title": "A Heterogeneous System for Real-Time Detection with AdaBoost",
 "venue": "high performance computing and communications",
 "year": 2016,
 "id": "001eef4f-1d00-4ae6-8b4f-7e66344bbc6e"}


{"abstract": "In this paper, a kind of novel jigsaw EBG structure is designed and applied into conformal antenna array",
 "authors": ["Yufei Liang", "Yan Zhang", "Tao Dong", "Shan-wei Lu"], 
"n_citation": 0, 
"references": [], 
"title": "A novel conformal jigsaw EBG structure design", 
"venue": "international conference on conceptual structures", 
"year": 2016, 
"id": "002e0b7e-d62f-4140-b015-1fe29a9acbaa"}

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Кажется, вы читаете файл json lines, который может выглядеть примерно так:

{key1: value1, key2: [value2, value3, value4], key3: value3}
{key1: value4, key2: [value5, value6], key3: value7}

Обратите внимание на запятые в конце, и каждая строка сама по себе являетсядопустимый json формат.

К счастью для вас, pandas может читать файл json lines напрямую, например так:

pd.read_json('test.json', lines=True)

Поскольку имена ваших столбцов точно такие же, как у вашего jsonключи, вам не нужно заранее настраивать пустой DataFrame.read_json сделает все за вас.Пример:

df = pd.read_json('test.json', lines=True)
print(df)

                                            abstract  ...   year
0  AdaBoost algorithm based on Haar-like features...  ...   2016
1  In this paper, a kind of novel jigsaw EBG stru...  ...   2016

[2 rows x 8 columns]

Еще более удачно, если вы ограничены размером, вы можете использовать аргумент chunksize, который превращает метод .read_json в генератор:

json_reader = pd.read_json('test.json', lines=True, chunksize=10000)

Теперь, когда вы перебираете json_reader, каждый раз он выводит DataFrame из следующих 10 000 строк из файла json.Пример:

for j in json_reader:
  print(j)

                                            abstract  ...   year
0  AdaBoost algorithm based on Haar-like features...  ...   2016
1  In this paper, a kind of novel jigsaw EBG stru...  ...   2016

[2 rows x 8 columns]
                                            abstract  ...   year
2  AdaBoost algorithm based on Haar-like features...  ...   2016
3  In this paper, a kind of novel jigsaw EBG stru...  ...   2016

[2 rows x 8 columns]
                                            abstract  ...   year
4  AdaBoost algorithm based on Haar-like features...  ...   2016
5  In this paper, a kind of novel jigsaw EBG stru...  ...   2016

[2 rows x 8 columns]

Комбинируя все эти обретенные знания, вы можете использовать chunksize=10000 и выводить фрагмент DataFrame как отдельный csv, например, так:

for i, df in enumerate(json_reader):
  df.to_csv('my_csv_file_{}'.format(i))

ЗдесьВы заметили, что я объединил функцию enumerate(), чтобы мы могли получить индексный номер с автоинкрементом, и функцию str.format() для добавления номера индекса к сгенерированному файлу csv.

Вы можете увидетьпример здесь на Repl.it.

0 голосов
/ 26 ноября 2018

Вы храните все свои данные в памяти, один раз в виде строк и один раз в качестве кадра данных.Это может замедлить вашу обработку.

Использование csv -модуля позволит вам обработать файл в потоковом режиме:

import json
import csv

with open('test.json') as lines, open('data.csv', 'w') as output:
    output = csv.DictWriter(output, ['abstract','authors','n_citation',"references","title","venue","year",'id'])
    output.writeheader()
    for line in lines:
        line = line.strip()
        if line[0] == '{' and line[-1] == '}':
            output.writerow(json.loads(line))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...