Here is a question from an absolute beginner python developer.
Here is the challenge I have :)
not being able to access the "status" in this json file:
[{
"id": 0,
"sellerId": "HHH",
"lat": 90.293846,
"lon": 15.837098,
"evses": [{
"id": 0,
"status": 1,
"connectors": [{
"type": "Hyyyyp",
"maxKw": 22
}
]
}, {
"id": 2001,
"status": 2,
"connectors": [{
"type": "Hyyyyp",
"maxKw": 22
}
]
}, {
"id": 2002,
"status": 1,
"connectors": [{
"type": "Hyyyyp",
"maxKw": 22
}
]
}, {
"id": 2003,
"status": 1,
"connectors": [{
"type": "Hyyyp",
"maxKw": 22
}
]
}
]
}, {
"id": 10001,
"sellerId": 7705,
"lat": 12.59962,
"lon": 40.8767,
"evses": [{
"id": 10001,
"status": 1,
"connectors": [{
"type": "Tyyyyp",
"maxKw": 22
}
]
}, {
"id": 10002,
"status": 2,
"connectors": [{
"type": "Tyyyyp",
"maxKw": 22
}
]
}, {
"id": 10003,
"status": 2,
"connectors": [{
"type": "Tyyyyp",
"maxKw": 22
}
]
}, {
"id": 10004,
"status": 2,
"connectors": [{
"type": "Tyyyyp",
"maxKw": 22
}
]
}
]
}, {
for the "id:10001" there are 3 cases which "status: 2".
So.. how do I print 3 for id:10001?
I guess I need to have an array for storying the ids itself and another array for storying the number of "status:2" for each id.
Here is my code:
firs I do print id:
with open('sample.json') as f:
data = json.load(f)
print(id['id'])
Then I think I need to access array evses:
So here is what I do:
print(data['evses'][0]['id']['status'])
But I get error on this line.
Following clarification from OP, this would be my proposed solution:
import json
from collections import Counter
def get_status_2_for_id(filename):
count = Counter()
with open(filename) as jdata:
for e in json.load(jdata):
if (id_ := e.get('id')) is not None:
for f in e.get('evses', []):
if f.get('status') == 2:
count[id_] += 1
return count.items()
for id_, count in get_status_2_for_id('sample.json'):
print(f'id={id_} count={count}')
Output:
id=0 count=1
id=10001 count=3
Let's say you take a single JSON record of your data which is below
record = {
"id": 10001,
"sellerId": 7705,
"lat": 12.59962,
"lon": 40.8767,
"evses": [{
"id": 10001,
"status": 1,
"connectors": [{
"type": "Tyyyyp",
"maxKw": 22
}
]
}, {
"id": 10002,
"status": 2,
"connectors": [{
"type": "Tyyyyp",
"maxKw": 22
}
]
}, {
"id": 10003,
"status": 2,
"connectors": [{
"type": "Tyyyyp",
"maxKw": 22
}
]
}, {
"id": 10004,
"status": 2,
"connectors": [{
"type": "Tyyyyp",
"maxKw": 22
}
]
}
]
}
From this data record above, if you want to count the number of occurences of a particular status you can do something like below
status_2_count = [stp["status"] for stp in record["evses"]].count(2)
We just generate a list of all statuses in the record["evses"] and count the occurence of a particualr status.
You can make this a function, and repeat it for other records in the file.
You can try this if its stored as a variable:
for status in json_data["evses"]:
print('status = ', status['status'])
And this if it's stored in a file:
import json
status_pts = 1
with open('file.json') as json_file:
data = json.loads(json_file.read())
ls = data[0]['evses']
for s in ls:
if s['status'] == status_pts:
print('id:', s['id'], "number of status =", status_pts)
Also, your json data wasn't closed off, the very last line has:
}, {
It needed:
}]
Related
I've never heard of or found an option for what I'm looking for, but maybe someone knows a way:
To collect the data from a JSON I need to map manually it like this:
events = response['events']
for event in events:
tournament_name = event['tournament']['name']
tournament_slug = event['tournament']['slug']
tournament_category_name = event['tournament']['category']['name']
tournament_category_slug = event['tournament']['category']['slug']
tournament_category_sport_name = event['tournament']['category']['sport']['name']
tournament_category_sport_slug = event['tournament']['category']['sport']['slug']
tournament_category_sport_id = event['tournament']['category']['sport']['id']
The complete model is this:
{
"events": [
{
"tournament": {
"name": "Serie A",
"slug": "serie-a",
"category": {
"name": "Italy",
"slug": "italy",
"sport": {
"name": "Football",
"slug": "football",
"id": 1
},
"id": 31,
"flag": "italy",
"alpha2": "IT"
},
"uniqueTournament": {
"name": "Serie A",
"slug": "serie-a",
"category": {
"name": "Italy",
"slug": "italy",
"sport": {
"name": "Football",
"slug": "football",
"id": 1
},
"id": 31,
"flag": "italy",
"alpha2": "IT"
},
"userCount": 586563,
"id": 23,
"hasEventPlayerStatistics": true
},
"priority": 254,
"id": 33
},
"roundInfo": {
"round": 24
},
"customId": "Kdbsfeb",
"status": {
"code": 7,
"description": "2nd half",
"type": "inprogress"
},
"winnerCode": 0,
"homeTeam": {
"name": "Bologna",
"slug": "bologna",
"shortName": "Bologna",
"gender": "M",
"userCount": 39429,
"nameCode": "BOL",
"national": false,
"type": 0,
"id": 2685,
"subTeams": [
],
"teamColors": {
"primary": "#003366",
"secondary": "#cc0000",
"text": "#cc0000"
}
},
"awayTeam": {
"name": "Empoli",
"slug": "empoli",
"shortName": "Empoli",
"gender": "M",
"userCount": 31469,
"nameCode": "EMP",
"national": false,
"type": 0,
"id": 2705,
"subTeams": [
],
"teamColors": {
"primary": "#0d5696",
"secondary": "#ffffff",
"text": "#ffffff"
}
},
"homeScore": {
"current": 0,
"display": 0,
"period1": 0
},
"awayScore": {
"current": 0,
"display": 0,
"period1": 0
},
"coverage": 1,
"time": {
"initial": 2700,
"max": 5400,
"extra": 540,
"currentPeriodStartTimestamp": 1644159735
},
"changes": {
"changes": [
"status.code",
"status.description",
"time.currentPeriodStart"
],
"changeTimestamp": 1644159743
},
"hasGlobalHighlights": false,
"hasEventPlayerStatistics": true,
"hasEventPlayerHeatMap": true,
"id": 9645399,
"statusTime": {
"prefix": "",
"initial": 2700,
"max": 5400,
"timestamp": 1644159735,
"extra": 540
},
"startTimestamp": 1644156000,
"slug": "empoli-bologna",
"lastPeriod": "period2",
"finalResultOnly": false
}
]
}
In my example I am collecting 7 values.
But there are 83 possible values to be collected.
In case I want to get all the values options that exist in this JSON, is there any way to make this map sequence automatically to print so I can copy it to the code?
Because manually it takes too long to do and it's very tiring.
And the results of texts like print() in terminal would be something like:
tournament_name = event['tournament']['name']
tournament_slug = event['tournament']['slug']
...
...
...
And so on until delivering the 83 object paths with values to collect...
Then I could copy all the prints and paste into my Python file to retrieve the values or any other way to make the work easier.
If the elements in the events arrays are the same, this code works without errors.
def get_prints(recode: dict):
for key in recode.keys():
if type(recode[key]) == dict:
for sub_print in get_prints(recode[key]):
yield [key] + sub_print
else:
yield [key]
class Automater:
def __init__(self,name: str):
"""
Params:
name: name of json
"""
self.name = name
def get_print(self,*args):
"""
Params:
*args: keys json
"""
return '_'.join(args) + ' = ' + self.name + ''.join([f"['{arg}']" for arg in args])
For example, this code:
dicts = {
'tournament':{
'name':"any name",
'slug':'somthing else',
'sport':{
'name':'sport',
'anotherdict':{
'yes':True
}
}
}
}
list_names = get_prints(dicts)
for name in list_names:
print(auto.get_print(*name))
Gives this output:
tournament_name = event['tournament']['name']
tournament_slug = event['tournament']['slug']
tournament_sport_name = event['tournament']['sport']['name']
tournament_sport_anotherdict_yes = event['tournament']['sport']['anotherdict']['yes']
I am new to converting pandas dataframe into json object.
I have a data frame:
Expected json output after conversion is this.
{
"Name": {
"id": "Max",
},
"Favorites" : [
{
"id":"Apple",
"priority":"High",
"Count":"4"
},
{
"id":"Oranges",
"priority":"Medium",
"Count":"2"
},
{
"id":"Banana",
"priority":"Low",
"Count":"1"
}
]
}
Here's a freebie. Hope it helps you learn how to write it yourself in the future :)
output = []
for index, row in df.iterrows():
entry = {
"Name": {
"id": row['Names']
},
"Favorites": [
{
"id": row['High_Priority_Goods_Name'],
"priority": "High",
"count": row['High_Priority_Goods_Count']
},
{
"id": row['Medium_Priority_Goods_Name'],
"priority": "Medium",
"count": row['Medium_Priority_Goods_Count']
},
{
"id": row['Low_Priority_Goods_Name'],
"priority": "Low",
"count": row['Low_Priority_Goods_Count']
}
]
}
output.append(entry)
print(output)
I am working with one of my requirement
My requirement: I need to pick and print only 3rd "id" from "syrap" list from the nested json file. I am not getting desired output. Any help will be appreciated.
Test file:
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{ "process": "abc",
"mix": "0303",
"syrap":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"rate": 0.55,
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
Expected output in a csv:
0001,donut,abc,0303,1003
My code:
import requests
import json
import csv
f = open('testdata.json')
data = json.load(f)
f.close()
f = csv.writer(open('testout.csv', 'wb+'))
for item in data:
f.writerow([item['id'], item[type], item['batters'][0]['process'],
item['batters'][0]['mix'],
item['batters'][0]['syrap'][0]['id'],
item['batters'][0]['syrap'][1]['id'],
item['batters'][0]['syrap'][2]['id'])
Here is some sample code showing how you can iterate through json content parsed as a dictionary:
import json
json_str = '''{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{ "process": "abc",
"mix": "0303",
"syrap":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"rate": 0.55,
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
'''
jsondict = json.loads(json_str)
syrap_node = jsondict['batters']['syrap']
for item in syrap_node:
print (f'id:{item["id"]} type: {item["type"]}')
Simply, data[“batters”][“syrap”][2][“id”]
Much better way to achieve this would be
f = open('testout.csv', 'wb+')
with f:
fnames = ['id','type','process','mix','syrap']
writer = csv.DictWriter(f, fieldnames=fnames)
writer.writeheader()
for item in data:
print item
writer.writerow({'id' : item['id'], 'type': item['type'],
'process' : item['batters']['process'],
'mix': item['batters']['mix'],
'syrap': item['batters']['syrap'][2]['id']})
You need to make sure that data is actually a list. if it is not a list, don't use for loop.
simply,
writer.writerow({'id' : data['id'], 'type': data['type'],
'process' : data['batters']['process'],
'mix': data['batters']['mix'],
'syrap': data['batters']['syrap'][2]['id']})
I have two JSONs. One has entries like this:
one.json
"data": [
{
"results": {
"counties": {
"32": 0,
"96": 0,
"12": 0
},
"cities": {
"total": 32,
"reporting": 0
}
},
"element_id": 999
},
The other has entries like this:
two.json
"data": [
{
"year": 2020,
"state": "Virginia",
"entries": [
{
"first_name": "Robert",
"last_name": "Smith",
"entry_id": 15723,
"pivot": {
"county_id": 32,
"element_id": 999
}
},
{
"first_name": "Benjamin",
"last_name": "Carter",
"entry_id": 15724,
"pivot": {
"county_id": 34,
"element_id": 999
}
}
],
"element_id": 999,
},
I want to join one.json to two.json based on element_id. The JSONs have lots of element_ids so there is an element of finding the right one to append to. Is there a way to use append to do this based on element_id without having to use a for loop? An appended version of the second JSON above would look like this:
joined.json
"data": [
{
"year": 2020,
"state": "Washington",
"entries": [
{
"first_name": "Robert",
"last_name": "Smith",
"entry_id": 15723,
"pivot": {
"county_id": 32,
"element_id": 999
}
},
{
"first_name": "Benjamin",
"last_name": "Carter",
"entry_id": 15724,
"pivot": {
"county_id": 34,
"element_id": 999
}
}
],
"element_id": 999,
{
"results": {
"counties": {
"32": 0,
"96": 0,
"12": 0
},
"cities": {
"total": 32,
"reporting": 0
}
},
},
What I have so far:
for item in one:
#this goes through one and saves each unique item in a couple variables
temp_id = item["element_id"]
temp_datachunk = item
#then I try to find those variables in two and if I find them, I append
for data in two:
if data["element_id"] == temp_id:
full_data = data.append(item)
print(full_data)
Right now, my attempt dies at the append. I get AttributeError: 'dict' object has no attribute 'append'.
Something like this should work:
source = '''
[{
"results": {
"counties": {
"32": 0,
"96": 0,
"12": 0
},
"cities": {
"total": 32,
"reporting": 0
}
},
"element_id": 999
}]
'''
target = """
[{
"year": 2020,
"state": "Virginia",
"entries": [{
"first_name": "Robert",
"last_name": "Smith",
"entry_id": 15723,
"pivot": {
"county_id": 32,
"element_id": 999
}
},
{
"first_name": "Benjamin",
"last_name": "Carter",
"entry_id": 15724,
"pivot": {
"county_id": 34,
"element_id": 999
}
}
],
"element_id": 999
}]
"""
source_j = json.loads(source)
target_j = json.loads(target)
jsonpath_expr = parse('$..element_id')
source_match = jsonpath_expr.find(source_j)
target_match = jsonpath_expr.find(target_j)
if source_match[0].value==target_match[0].value:
final = target_j+source_j
print(final)
The output is the combined json.
I have the following json:
{
"request": {
"id": "123",
"url": "/aa/bb/cc",
"method": "GET",
"timestamp": "2018-08-09T08:41:38.432Z"
},
"response": {
"status": {
"code": 200,
"message": "OK"
},
"items": [
{
"id": "aaa",
"name": "w1"
},
{
"id": "bbb",
"name": "w2"
},
{
"id": "ccc",
"name": "w3"
}
]
}
}
I need to loop over items and print each name. I've tried the following code which doesn't work.
response = requests.get(url)
data = json.loads(response.content)
for group in data['response']['items']:
print data['response']['items'][group]['name']
When i replace group with 0 for example, I can access the first name:
data['response']['items'][0]['name']
However, I don't know in advanced how many elements are in the array.
As Joel mentioned, in the for loop,
for group in data['response']['items']:
you are assigning group the value from data['response']['items']. Hence group contains the value :
[
{
"id": "aaa",
"name": "w1"
},
{
"id": "bbb",
"name": "w2"
},
{
"id": "ccc",
"name": "w3"
}
]
So all you need to do is
print group['name']
You can use Pandas module and call read_json function.
import pandas as pd
df = pd.read_json(your_json_file.json)
for i in df.response['items']:
print(i['name'])
# w1
# w2
# w3
You could try this:
for i in range (0,len(d['response']['items'])):
print(d['response']['items'][i]['name'])
Output:
w1
w2
w3