2

I am trying here to use json_normalize to somehow format the output of an API, but I keep getting a faulty and empty csv file. I tried to change df2 = pd.json_normalize(response, record_path=['LIST']) , but keep getting this error message:

TypeError: byte indices must be integers or slices, not str

Could you please guide me on what am I doing wrong ?

Thanks a lot !

import requests
import json
import pandas as pd

url = "https://*hidden*Results/"

payload = json.dumps({
  "id": 12345
})
headers = {
  'Authorization': 'Basic *hidden*',
  'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=payload)


df1 = pd.DataFrame(response).iloc[:,:-2]
df2 = pd.json_normalize(response, record_path=None)

df = pd.concat([df1, df2], axis=1)
df.to_csv("test.csv", index=False)
3
  • I'm not expert with pandas. Just to understand, it works with record_path=None bot not when you pass record_path=['LIST']? The documentation says that can receive record_path: str or list of str, default None, have you tried only with 'LIST'? Commented Apr 11, 2022 at 19:38
  • Do you have the sample of the json file you are working with? Commented Apr 11, 2022 at 19:42
  • It is not working neither with record_path=['LIST'], neither with =None. Unfortunately, cannot really share the json file. Commented Apr 11, 2022 at 19:55

1 Answer 1

3

You are passing the variable response in the call:

df2 = pd.json_normalize(response, record_path=None)

Which is an a requests.models.Response Object and you need to pass a dict, so you need to do something like pd.json_normalize(response.json(), record_path=['LIST'])

I tried it with this example and works:

>>> import pandas as pd
>>> data = [
...     {
...         "state": "Florida",
...         "shortname": "FL",
...         "info": {"governor": "Rick Scott"},
...         "counties": [
...             {"name": "Dade", "population": 12345},
...             {"name": "Broward", "population": 40000},
...             {"name": "Palm Beach", "population": 60000},
...         ],
...     },
...     {
...         "state": "Ohio",
...         "shortname": "OH",
...         "info": {"governor": "John Kasich"},
...         "counties": [
...             {"name": "Summit", "population": 1234},
...             {"name": "Cuyahoga", "population": 1337},
...         ],
...     },
... ]
>>> result = pd.json_normalize(data, ["counties"])
>>> result
         name  population
0        Dade       12345
1     Broward       40000
2  Palm Beach       60000
3      Summit        1234
4    Cuyahoga        1337

EDIT I will try to do this:

import requests
import json
import pandas as pd

url = "https://*hidden*Results/"

payload = json.dumps({
  "id": 12345
})
headers = {
  'Authorization': 'Basic *hidden*',
  'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=payload)

json_response = response.json()

df1 = pd.DataFrame(json_response).iloc[:,:-2]
df2 = pd.json_normalize(json_response, record_path=['LIST'])

df = pd.concat([df1, df2], axis=1)
df.to_csv("test.csv", index=False)
Sign up to request clarification or add additional context in comments.

7 Comments

Hm.. seems like the same error message on line: result = pd.json_normalize(data, ["counties"]) TypeError: byte indices must be integers or slices, not str
This example is adapted from the pandas docs so you can try the one from the docs, but I have checked it again and it works fine for me. Are you sure this error is coming from the example I sent you?
Update: After running the below, I got the message: Empty DataFrame Columns: [] Index: [0] //code// df = pd.DataFrame(response) df = pd.json_normalize(df) print(df)
is the variable response a dictionary? because remember that pd.DataFrame(...) is waiting for a dictionary where the 3 dots are.
In order to get a dictionary from the response object do this: pd.DataFrame(response.json())
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.