I am new Python user, who decided to use Python to create simple application that allows for converting json files into flat table and saving the output in cvs format. I was wondering if you could give me some advice how I could improve my code to make it work in more efficient way. I am asking since if I convert relatively small files everything works just fine but when I try to convert ~200 MB file it starts to take a while. I am afraid that when I begin to work with bigger files it might take quite some time to convert my datasets.
Here is my code, which I created with help of this great blog post about flattening json objects :
import sys, os, json, tkFileDialog, tkMessageBox
from Tkinter import *
from pandas.io.json import json_normalize
def openFile():
currdir = os.getcwd()
filename = tkFileDialog.askopenfilename(
initialdir = currdir,
title='Please select a file',
filetypes=[('JSON file','.json')])
return filename
def loading_file(path):
#File path
file_path = path
#Loading json file
json_data = open(file_path)
data = json.load(json_data)
return data
#Function that recursively extracts values out of the object into a flattened dictionary
def flatten_json(data):
flat = [] #list of flat dictionaries
def flatten(y):
out = {}
def flatten2(x, name=''):
if type(x) is dict:
for a in x:
if a == "name":
flatten2(x["value"], name + x[a] + '_')
else:
flatten2(x[a], name + a + '_')
elif type(x) is list:
for a in x:
flatten2(a, name + '_')
else:
out[name[:-1]] = x
flatten2(y)
return out
#Loop needed to flatten multiple objects
for i in range(len(data)):
flat.append(flatten(data[i]).copy())
return json_normalize(flat)
#Outputing normalized data into csv
def csv_out(data, path):
#creating csv file name
name = '~/Desktop/' + os.path.basename(os.path.splitext(path)[0]) + '.csv'
#converting to the csv
data.to_csv(name, encoding='utf-8') #'~/Desktop/out.csv'
def done():
tkMessageBox.showinfo('json2csv',"DONE!")
def main():
filepath = openFile()
data_file = loading_file(filepath)
table = flatten_json(data_file)
csv_out(table, filepath)
done()
### Application Interface ###
tk = Tk()
#Creating window:
tk.geometry('250x150+600+300')
tk.title('JSON2CSV')
#Creating convert button
convertbutton = Button(tk, text = 'Convert to .csv', command = main)
convertbutton.place(x = 25, y = 50)
tk.mainloop()
Here you will find short example of the json structure I work with:
[{
"_id": {
"id": "123"
},
"device": {
"browser": "Safari",
"category": "d",
"os": "Mac"
},
"exID": {
"$oid": "123"
},
"extreme": false,
"geo": {
"city": "London",
"country": "United Kingdom",
"countryCode": "UK",
"ip": "00.000.000.0"
},
"viewed": {
"$date": "2011-02-12"
},
"attributes": [{
"name": "gender",
"numeric": 0,
"value": 0
}, {
"name": "email",
"value": false
}],
"change": [{
"id": {
"$id": "1231"
},
"seen": [{
"$date": "2011-02-12"
}]
}]
}, {
"_id": {
"id": "456"
},
"device": {
"browser": "Chrome 47",
"category": "d",
"os": "Windows"
},
"exID": {
"$oid": "345"
},
"extreme": false,
"geo": {
"city": "Berlin",
"country": "Germany",
"countryCode": "DE",
"ip": "00.000.000.0"
},
"viewed": {
"$date": "2011-05-12"
},
"attributes": [{
"name": "gender",
"numeric": 1,
"value": 1
}, {
"name": "email",
"value": true
}],
"change": [{
"id": {
"$id": "1231"
},
"seen": [{
"$date": "2011-02-12"
}]
}]
}]