I'm working with a pickled file in Python, and I need to extract the data from it. The data was saved as a dictionary:
I read it
import pickle
data = pickle.load( open("MyData.p", "rb") )
I read one dictionary:
data[0]
[{'StartTime': '2018-04-01 11:11:28',
'Name': 'AA',
'StudyName': '2018{AF4}',
'Data': [(10829.162109375,
13013.4033203125),
(11050.34375,
13063.3125),
(11514.7509765625,
13103.005859375)],
'Times': (5514.899,
5542.091,
5952.291),
'startOffset': 0.0}]
and get all the fields and can see it if printed. One of the fields is called "StartTime". However, when I want to access the field says
data[0]["StartTime"]
TypeError: list indices must be integers or slices, not str
Same with all fields.
How can I access the fields individually?
You can always just pretty print the data to see what you got:
import pprint
pprint.pprint(data)
In your specific case, try this:
print(data[0][0]["StartTime"])
There is another list you need to select the 0 element from.
data[0][0]["StartTime"]
Related
I am new to python coding, but I currently have a Json object that has different values, ex.
{"term_id":{"url":"http://library.austintexas.gov/taxonomy/term/205"},"name":"Ruiz Branch","address":{"latitude":"30.230228","longitude":"-97.706314"}}
and I would like to return the json object with only the adress and term_id value.
Lets say:
a = {"term_id":{"url":"http://library.austintexas.gov/taxonomy/term/205"},"name":"Ruiz Branch","address":{"latitude":"30.230228","longitude":"-97.706314"}}
address = a['address']
print(address)
result
{"latitude":"30.230228","longitude":"-97.706314"}
You could delete the element you don't want like this:
import json
text = '{"term_id":{"url":"http://library.austintexas.gov/taxonomy/term/205"},"name":"Ruiz Branch","address":{"latitude":"30.230228","longitude":"-97.706314"}}'
json_object = json.loads(text)
del json_object['name']
print(json_object)
{'term_id': {'url': 'http://library.austintexas.gov/taxonomy/term/205'}, 'address': {'latitude': '30.230228', 'longitude': '-97.706314'}}
If there are other possible extra elements, you could instead create a new json object to which you add only the elements you want from the original object.
If I have Json data that looks like this:
import json
rawData= {
"Date": "2020-08-16T13:37:22.501743", "MeterReading": 199
}
jsonData = json.dumps(rawData)
print(jsonData)
How could I verify with a boolean statement jsonData contains a legitimate time stamp (that pandas would understand) and the MeterReading would either be a float or integer value?
Is converting json object to list marching down the correct path?
l = list(rawData.values())
I can print these values individually but I think they are still strings...?
print(l[0], l[1])
Any tips greatly appreciated..
In below program, I have "data" which contains a dictionary and list. I am trying to read the value of "role" but getting the error:
import json
data = {"users":[{"user_id":"11w","device_id":"AQ","role":"OWN","links":{"rel":"self","href":"test_link"}}]}
k= json.loads(data)
role= k["users"]["role"]
print role
Error : TypeError: list indices must be integers, not str
You have a dictionary which contains a list of dictionaries, not a dictionary which contains a dictionary. And lists can only be indexed with integers (and slices, but they also contain integers).
To get the role of the first (and only one in this example) user, just use this:
role = k["users"][0]["role"]
print role
# OWN
Or, if you have multiple users, iterate over them:
for user in k["users"]:
print user["role"]
Looking at this line by line:
data = {"users":[{"user_id":"11w","device_id":"AQ","role":"OWN","links":{"rel":"self","href":"test_link"}}]}
data now holds a dictionary of a list of a dictionary.
k = json.loads(data)
Gives a json TypeError as json.loads needs to be passed a string, not a python data structure like data.
role = k["users"]["role"]
As you have discovered this doesn't work. Let's find the data step by step:
print(data["users"])
[{'user_id': '11w', 'device_id': 'AQ', 'role': 'OWN', 'links': {'rel': 'self', 'href': 'test_link'}}]
Note that this is a list ("[...]") not a dictionary. To access this list members you use integers, not strings. So next step extract the first (and only) member of this list:
print(data["users"][0])
{'user_id': '11w', 'device_id': 'AQ', 'role': 'OWN', 'links': {'rel': 'self', 'href': 'test_link'}}
Now we have the nested dictionary which we can lookup by key string:
print(data["users"][0]["role"])
'OWN'
Finally we have the answer you are looking for.
A json-file which has unique markers (or [more appropriate] field-names) preceeding the values is (rather) easy to dissect, because you can perform a string search on the unique markers/field-names to find within the string the first and last position of the characters of the value, and with that info you can pinpoint the position of the value, and extract the value.
Have performed that function with various lua-scripts and Python-scripts (also on xml-files).
Now need to extract values from a json-file which does not have unique markers/ field-names, but just a multiple occurrence of "value_type" and "value", preceeding the 'name', respectively the 'value': see below.
{
"software_version": "NRZ-2017-099",
"age":"78",
"sensordatavalues":[
{"value_type":"SDS_P1","value":"4.43"},
{"value_type":"SDS_P2","value":"3.80"},
{"value_type":"temperature","value":"20.10"},
{"value_type":"humidity","value":"44.50"},
{"value_type":"samples","value":"614292"},
{"value_type":"min_micro","value":"233"},
{"value_type":"max_micro","value":"25951"},
{"value_type":"signal","value":"-66"}
]
}
Experience as described above does not provide working solution.
Question: In this json-filelayout, how to directly extract the specific, individual values (preferably by lua-script)?
[Or might XML-parsing provide an easier solution?]
Here is Python to read the JSON file and make it more convenient:
import json
import pprint
with open("/tmp/foo.json") as j:
data = json.load(j)
for sdv in data.pop('sensordatavalues'):
data[sdv['value_type']] = sdv['value']
pprint.pprint(data)
The results:
{'SDS_P1': '4.43',
'SDS_P2': '3.80',
'age': '78',
'humidity': '44.50',
'max_micro': '25951',
'min_micro': '233',
'samples': '614292',
'signal': '-66',
'software_version': 'NRZ-2017-099',
'temperature': '20.10'}
You might want to have a look into filter functions.
E.g. in your example json to get only the dict that contains the value for samples you could go by:
sample_sensordata = list(filter(lambda d: d["value_type"] == "samples", your_json_dict["sensordatavalues"]))
sample_value = sample_sensordata["value"]
To make a dictionary like Ned Batchelder said you could also go with a dict comprehension like this:
sensor_data_dict = {d['value_type']: d['value'] for d in a}
and then get the value you want just by sensor_data_dict['<ValueTypeYouAreLookingFor>']
A little bit late and I'm trying Anvil in which the previous answers didn't work. just for the curious people.
resp = anvil.http.request("http://<ipaddress>/data.json", json=True)
#print(resp) # prints json file
tempdict = resp['sensordatavalues'][2].values()
humiddict = resp['sensordatavalues'][3].values()
temperature = float(list(tempdict)[1])
humidity = float(list(humiddict)[1])
print(temperature)
print(humidity)
I am incredibly new to python.
I have an array full of json objects. Some of the json objects contain duplicated values. The array looks like this:
[{"id":"1","name":"Paul","age":"21"},
{"id":"2","name":"Peter","age":"22"},
{"id":"3","name":"Paul","age":"23"}]
What I am trying to do is to remove an item if the name is the same as another json object, and leave the first one in the array.
So in this case I should be left with
[{"id":"1"."name":"Paul","age":"21"},
{"id":"2","name":"Peter","age":"22"}]
The code I currently have can be seen below and is largely based on this answer:
import json
ds = json.loads('python.json') #this file contains the json
unique_stuff = { each['name'] : each for each in ds }.values()
all_ids = [ each['name'] for each in ds ]
unique_stuff = [ ds[ all_ids.index(text) ] for text in set(texts) ]
print unique_stuff
I am not even sure that this line is working ds = json.loads('python.json') #this file contains the json as when I try and print ds nothing shows up in the console.
You might have overdone in your approach. I might tend to rewrite the list as a dictionary with "name" as a key and then fetch the values
ds = [{"id":"1","name":"Paul","age":"21"},
{"id":"2","name":"Peter","age":"22"},
{"id":"3","name":"Paul","age":"23"}]
{elem["name"]:elem for elem in ds}.values()
Out[2]:
[{'age': '23', 'id': '3', 'name': 'Paul'},
{'age': '22', 'id': '2', 'name': 'Peter'}]
Off-course the items within the dictionary and the list may not be ordered, but I do not see much of a concern. If it is, let us know and we can think over it.
If you need to keep the first instance of "Paul" in your data a dictionary comprehension gives you the opposite result.
A simple solution could be as following
new = []
seen = set()
for record in old:
name = record['name']
if name not in seen:
seen.add(name)
new.append(record)
del seen
First of all, your json snippet has invalid format - there are dot instead of commas separating some keys.
You can solve your problem using a dictionary with names as keys:
import json
with open('python.json') as fp:
ds = json.load(fp) #this file contains the json
mem = {}
for record in ds:
name = record["name"]
if name not in mem:
mem[name] = record
print mem.values()