How to get JSON data in expected format using Python json.dump

Question:

I read multiple sheets from excel files and combine then to a single JSON file.

Sample Data:

df1

    Metric                      Value
0   salesamount                 9.0
1   salespercentage             80.0
2   salesdays                   56.0
3   salesconversionpercentage   0.3


df2

    Metric      Value
0   FromBudget  4K
1   ToBudget    5K


df3

    Metric                  Value
0   Objective               Customer Engagement
1   ExpectedOutcomesales    0.2
2   ExpectedOutcomeweeks    8 weeks

I then convert them into dictionary using:

s = dict(zip(df1.iloc[:,0], df1.iloc[:,1]))
eb = dict(zip(df2.iloc[:,0], df2.iloc[:,1]))
eo = dict(zip(df3.iloc[:,0], df3.iloc[:,1]))

I then store above items is a key ExpectedPlanPerformance using:

mydct = {
        'ExpectedPlanPerformance' : 
                                    {
                                     'EstimatedBudget' : eb,
                                     'Sales' : s,
                                     'ExpectedOutcome' : eo
                                    }
        }
mydct

{'ExpectedPlanPerformance': {'EstimatedBudget': {'FromBudget': '4K',
   'ToBudget': '5K'},
  'Sales': ({'salesamount': '9.0',
    'salespercentage': '80.0',
    'salesdays': '56.0',
    'salesconversionpercentage': '0.3'},),
  'ExpectedOutcome': {'Objective': 'Customer Engagement',
   'ExpectedOutcomesales': 0.2,
   'ExpectedOutcomeweeks': '8 weeks'}}}

I write this dictionary to JSON using:

outfile = open(‘file.json’,’w’)
json.dump(mydct, outfile, indent = 4)
outfile.close()

The JSON file I append to already contains other elements. Those elements are actually dataframes that were converted to JSON format using:

json.loads(df.to_json(orient = 'records'))

Once such dataframes are converted to JSON format, they are stored in a dictionary as above and written to file using same json.dump.

But the output in the file is in below format:

{
    "ExpectedPlanPerformance": {
        "EstimatedBudget": "{"FromBudget": "4K", "ToBudget": "5K"}",
        "Sales": "{"salesamount": "9.0", "salespercentage": "80.0", "salesdays": "56.0", "salesconversionpercentage": "0.3"}",
        "ExpectedOutcome": "{"Objective": "Customer Engagement", "ExpectedOutcomesales": "20%", "ExpectedOutcomeweeks": "8 weeks"}"
    }

Whereas some other elements are like below:

"TotalYield": [
    "225K"
],
"TotalYieldText": [
    "Lorem ipsum door sit amet"
],

Can someone please let me know how to fix this, expected output is as below:

"ExpectedPlanPerformance": [{
    "ExpectedOutcome": {
        "Objective": "Customer Engagement",
        "ExpectedOutcomesales": "20%",
        "ExpectedOutcomeweeks": "8 weeks"
    },
    "Sales": {
        "salesamount": "9 ",
        "salespercentage": "80",
        "salesdays": "56",
        "salesconversionpercentage": "0.3"
    },
    "EstimatedBudget": {
        "FromBudget": "4K",
        "ToBudget": "5K"
    }
}],
Asked By: Karthik S

||

Answers:

Try:

out = {
    "ExpectedPlanPerformance": [
        {
            "ExpectedOutcome": dict(zip(df3.Metric, df3.Value)),
            "Sales": dict(zip(df1.Metric, df1.Value)),
            "EstimatedBudget": dict(zip(df2.Metric, df2.Value)),
        }
    ]
}

print(out)

Prints:

{
    "ExpectedPlanPerformance": [
        {
            "ExpectedOutcome": {
                "Objective": "Customer Engagement",
                "ExpectedOutcomesales": "0.2",
                "ExpectedOutcomeweeks": "8 weeks",
            },
            "Sales": {
                "salesamount": 9.0,
                "salespercentage": 80.0,
                "salesdays": 56.0,
                "salesconversionpercentage": 0.3,
            },
            "EstimatedBudget": {"FromBudget": "4K", "ToBudget": "5K"},
        }
    ]
}

To save out to a file:

import json

with open("your_file.json", "w") as f_in:
    json.dump(out, f_in, indent=4)
Answered By: Andrej Kesely
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.