user1335606
user1335606

Reputation: 503

Convert float string to float in json

I have a json(test.json) file with the below data. I have around 10000 records. I need to convert value from string to float write in the new file(test1.json). How can I do do this from Python?

{
    "name":"test001",
    "cat":"test",
    "loc":"x loc",
    "ings":[
        {
            "name":"rrrrrr",
            "value":"13.0"
        },
        {
            "name":"hhhh",
            "value":"18.0"
        }
    ],
    "nums":[
        {
            "name":"kkkk",
            "value":"82.05"
        },
        {
            "name":"uuuuu",
            "value":"53.55"
        }
    ]
},
{
    "name":"test002",
    "cat":"test1",
    "loc":"y loc",
    "ings":[
        {
            "name":"trtrtr",
            "value":"11.0"
        },
        {
            "name":"wewew",
            "value":"19.0"
        }
    ],
    "nums":[
        {
            "name":"iuyt",
            "value":"122.05"
        },
        {
            "name":"oiui",
            "value":"15.5"
        }
    ]
}

resulting json file(test1.json) should be like below...

{
    "name":"test001",
    "cat":"test",
    "loc":"x loc",
    "ings":[
        {
            "name":"rrrrrr",
            "value":13.0
        },
        {
            "name":"hhhh",
            "value":18.0
        }
    ],
    "nums":[
        {
            "name":"kkkk",
            "value":82.05
        },
        {
            "name":"uuuuu",
            "value":53.55
        }
    ]
},
{
    "name":"test002",
    "cat":"test1",
    "loc":"y loc",
    "ings":[
        {
            "name":"trtrtr",
            "value":11.0
        },
        {
            "name":"wewew",
            "value":19.0
        }
    ],
    "nums":[
        {
            "name":"iuyt",
            "value":122.05
        },
        {
            "name":"oiui",
            "value":15.5
        }
    ]
}

Upvotes: 3

Views: 8865

Answers (3)

pasujemito
pasujemito

Reputation: 332

If you have a single or specific key value object, you can reiterate the value containing alphabetical strings or numerical strings, then map and check against their type with string.isnumeric():

dict = { 'a':'100', 'b':'200', 'c':'300', 'd':'four_hundred', 'e':'500' }
dict_parse = {k: int(v) if v.isnumeric() else v for k, v in dict.items()}

>>> dict_parse
{ 'a': 100, 'b': 200, 'c': 300, 'd':'four_hundred', 'e':500}

when dealing with float numbers amend the if statement to replace decimal point, you can apply same principal to negative numbers:

dict = { 'a':'10.0', 'b':'20.12', 'c':'300.3', 'd':'four_hundred', 'e':'500' }
dict_parse = {k: float(v) if v.replace(".", "").isnumeric() else v for k, v in dict.items()}

>>> dict_parse
{ 'a': 10.0, 'b': 20.12, 'c': 300.3, 'd':'four_hundred', 'e':500}

Upvotes: 0

smac89
smac89

Reputation: 43254

You can provide an object_hook to the json.loads method which will allow you to modify any object (dicts) found within the json:

import json

json_data = """
[{
    "name":"test001",
    "cat":"test",
    "loc":"x loc",
    "ings":[
        {
            "name":"rrrrrr",
            "value":"13.0"
        },
        {
            "name":"hhhh",
            "value":"18.0"
        }
    ],
    "nums":[
        {
            "name":"kkkk",
            "value":"82.05"
        },
        {
            "name":"uuuuu",
            "value":"53.55"
        }
    ]
},
{
    "name":"test002",
    "cat":"test1",
    "loc":"y loc",
    "ings":[
        {
            "name":"trtrtr",
            "value":"11.0"
        },
        {
            "name":"wewew",
            "value":"19.0"
        }
    ],
    "nums":[
        {
            "name":"iuyt",
            "value":"122.05"
        },
        {
            "name":"oiui",
            "value":"15.5"
        }
    ]
}]
"""

def as_float(obj):
    """Checks each dict passed to this function if it contains the key "value"
    Args:
        obj (dict): The object to decode

    Returns:
        dict: The new dictionary with changes if necessary
    """
    if "value" in obj:
        obj["value"] = float(obj["value"])
    return obj


if __name__ == '__main__':
    l = json.loads(json_data, object_hook=as_float)
    print (json.dumps(l, indent=4))

This results in what you want:

[
    {
        "loc": "x loc",
        "ings": [
            {
                "name": "rrrrrr",
                "value": 13.0
            },
            {
                "name": "hhhh",
                "value": 18.0
            }
        ],
        "name": "test001",
        "nums": [
            {
                "name": "kkkk",
                "value": 82.05
            },
            {
                "name": "uuuuu",
                "value": 53.55
            }
        ],
        "cat": "test"
    },
    {
        "loc": "y loc",
        "ings": [
            {
                "name": "trtrtr",
                "value": 11.0
            },
            {
                "name": "wewew",
                "value": 19.0
            }
        ],
        "name": "test002",
        "nums": [
            {
                "name": "iuyt",
                "value": 122.05
            },
            {
                "name": "oiui",
                "value": 15.5
            }
        ],
        "cat": "test1"
    }
]

To write to a file instead:

with open("out.json", "w+") as out:
    json.dump(l, out, indent=4)

Upvotes: 10

Tadhg McDonald-Jensen
Tadhg McDonald-Jensen

Reputation: 21474

You would need to recursively traverse the data and convert anything that looks like a float to a float:

def fix_floats(data):
    if isinstance(data,list):
        iterator = enumerate(data)
    elif isinstance(data,dict):
        iterator = data.items()
    else:
        raise TypeError("can only traverse list or dict")

    for i,value in iterator:
        if isinstance(value,(list,dict)):
            fix_floats(value)
        elif isinstance(value,str):
            try:
                data[i] = float(value)
            except ValueError:
                pass

It should do the trick:

my_data = [
        {   "name" : "rrrrrr", 
            "value" : "13.0"  }, 
        {   "name" : "hhhh", 
            "value" : "18.0"  }, 
        ]

fix_floats(my_data)

>>> my_data
[{'name': 'rrrrrr', 'value': 13.0}, {'name': 'hhhh', 'value': 18.0}]

Upvotes: 3

Related Questions