convert a df into a specific dictionary of dictionary in pandas - python-3.x

I have a df as shown below
Params Value
teachers 49
students 289
R 3.7
holidays 165
OS 18
Em_from 2020-02-29T20:00:00.000Z
Em_to 2020-03-20T20:00:00.000Z
Em_F 3
Em_C 2
sC_from 2020-03-31T20:00:00.000Z
sC_to 2020-05-29T20:00:00.000Z
sC_F 25
sC_C 31
From the above df I would like to convert that as a dictionary of dictionary as shown below.
dict:
{'teachers': 49,
'students': 289,
'R': 3.7,
'holidays': 165,
'OS':18,
'Em': {'from': '2020-02-29T20:00:00.000Z', 'to': '2020-03-20T20:00:00.000Z',
'F': 3, 'C': 2},
'sC': {'from': '2020-03-31T20:00:00.000Z', 'to': '2020-05-29T20:00:00.000Z',
'F': 25, 'C': 31}}

Use:
s = df['Params'].str.split('_')
m = s.str.len().eq(1)
d1 = df[m].set_index('Params')['Value'].to_dict()
d2 = df[~m].assign(Params=s.str[-1]).agg(tuple, axis=1)\
.groupby(s.str[0]).agg(lambda s: dict(s.tolist())).to_dict()
dct = {**d1, **d2}
Result:
{'Em': {'C': '2',
'F': '3',
'from': '2020-02-29T20:00:00.000Z',
'to': '2020-03-20T20:00:00.000Z'},
'OS': '18',
'R': '3.7',
'holidays': '165',
'sC': {'C': '31',
'F': '25',
'from': '2020-03-31T20:00:00.000Z',
'to': '2020-05-29T20:00:00.000Z'},
'students': '289',
'teachers': '49'}

Please always try to provide the data in a reproducible way, more people will be able to attempt the question
Dataset
Params = ['teachers','students','R','holidays','OS','Em_from','Em_to','Em_F','Em_C','sC_from','sC_to','sC_F','sC_C']
Value = ['49','289','3.7','165','18','2020-02-29T20:00:00.000Z','2020-03-20T20:00:00.000Z','3','2','2020-03-31T20:00:00.000Z','2020-05-29T20:00:00.000Z','25','31']
df = pd.DataFrame(zip(Params,Value),columns=["col1","col2"])
you can do something like
d = {}
for lst in df.values:
for k,v in zip(lst[0:],lst[1:]):
if any(name in k for name in ('Em_from', 'sC_from')):d[k.split('_')[0]] = {k.split('_')[1]:v}
elif any(name in k for name in ('Em_to', 'Em_F','Em_C','sC_to','sC_F','sC_C')):d[k.split('_')[0]][k.split('_')[1]] = v
else:d[k] = v
Output
{'teachers': '49',
'students': '289',
'R': '3.7',
'holidays': '165',
'OS': '18',
'Em': {'from': '2020-02-29T20:00:00.000Z',
'to': '2020-03-20T20:00:00.000Z',
'F': '3',
'C': '2'},
'sC': {'from': '2020-03-31T20:00:00.000Z',
'to': '2020-05-29T20:00:00.000Z',
'F': '25',
'C': '31'}}

panda's dataframes have a to_json method (see docs)
There are multiple examples there, but the general flow goes like this, let's say you have a dataframe called df:
import json
import pandas as pd
parsed = df.to_json()
df_json = json.loads(json_df)
Read the docs to see more examples and different parameters you may have to fiddle with.

Related

Python3 for loop over a dict

I am trying to get all the values individually for each asset (BCHUSD and TRXUSD).
What I want to do is something like this:
BCHUSD a = 301.340000 b = 301.160000 c = 301.280000
TRXUSD a = 0.0609450 b = 0.0609440 c = 0.0609540
Could someone tell me how I can do it please?
Regards!
import requests
import json
while True:
req = requests.get('https://api.kraken.com/0/public/Ticker?pair=BCHUSD,TRXUSD,XRPUSD')
print(req)
<Response [200]>
print(type(req))
<class 'requests.models.Response'>
obj = req.json()
print(type(obj))
<class 'dict'>
for k, v in obj.items():
if type(v) is dict and k:
for nk, nv in v.items():
print(nk, nv)
BCHUSD {'a': ['298.240000', '11', '11.000'], 'b': ['298.040000', '3', '3.000'], 'c':
['299.000000', '0.89507885'], 'v': ['38.42175237', '5614.56089299'], 'p':
['300.890848', '277.650439'], 't': [24, 2314], 'l': ['299.000000', '260.000000'], 'h':
['302.390000', '309.900000'], 'o': '299.000000'}
TRXUSD {'a': ['0.0608250', '4881', '4881.000'], 'b': ['0.0607820', '40500',
'40500.000'], 'c': ['0.0608630', '81.94337742'], 'v': ['21067.61432979',
'9622286.56922629'], 'p': ['0.0610566', '0.0589675'], 't': [25, 1729], 'l':
['0.0608630', '0.0562060'], 'h': ['0.0612840', '0.0618410'], 'o': '0.0611130'}
XXRPZUSD {'a': ['0.69018000', '666', '666.000'], 'b': ['0.69000000', '42829',
'42829.000'], 'c': ['0.69022000', '358.00000000'], 'v': ['287549.02071579',
'27810492.67564827'], 'p': ['0.69737332', '0.65981291'], 't': [429, 10340], 'l':
['0.69000000', '0.62229000'], 'h': ['0.70386000', '0.72105000'], 'o': '0.69935000'}
I think the following could help you as a starting point:
response_json = {
"title": "name",
"abc": {'a': [1,2,3], "b": [2,3,4]},
"ohter_stuff": "xxx",
"xyz": {'a': [10, 20 ,30], "b": [20, 30, 40]}
}
# select relevant key value pairs
data = {
key: value for key, value in response_json.items()
if isinstance(value, dict)
}
# get the inner subdict index length
length = len(data['abc']['a'])
# get the inner subdict keys
items = list(data['abc'].keys())
# loop and print
for index in range(length):
for name, subdict in data.items():
# join the items at index pairs into a string
index_items = " ".join(
f"{item} = {subdict[item][index]}"
for item in items
)
print(name, index_items)
This is a pure standard library python solution. If you can install other libraries, I would recommend to have a look into pandas.

merging and calculating sum in dictionaries

let_col= {'t': ['black', 'golden', 'silver'], 'f': ['blue', 'green'], 's': ['grey', 'yellow'], 'k': ['red', 'purple']}
col_pix = {'blue':150,'red':200,'green':160,'grey':240,'purple':210,'black':140,'yellow':120,'golden':130,'silver':200}
I would like to merge these two dictionaries as :
let_col_pixels = {'t': ['black':140, 'golden':130, 'silver':200],'f':[] ....}
Then I have to add total pixels for each letter. can someone please help me , I tried many things but still unable to do it. Thanks
I hope I understand your question right, this script will merge the dictionaries and adds key total_sum to each letter:
let_col= {'t': ['black', 'golden', 'silver'], 'f': ['blue', 'green'], 's': ['grey', 'yellow'], 'k': ['red', 'purple']}
col_pix = {'blue':150,'red':200,'green':160,'grey':240,'purple':210,'black':140,'yellow':120,'golden':130,'silver':200}
out = {k: dict(**v, total_sum=sum(v.values())) for k, v in {k:{vv: col_pix[vv] for vv in v} for k, v in let_col.items()}.items()}
from pprint import pprint
pprint(out)
Prints:
{'f': {'blue': 150, 'green': 160, 'total_sum': 310},
'k': {'purple': 210, 'red': 200, 'total_sum': 410},
's': {'grey': 240, 'total_sum': 360, 'yellow': 120},
't': {'black': 140, 'golden': 130, 'silver': 200, 'total_sum': 470}}

How to extend values in dictionaries using key in Python

How do I extend the values in a dictionary from a list of dictionaries using the keys as the main constraint, say:
d = {'a': (), 'b': 0, 'c': "", d: ""}
l = [ {'a': (23, 48), 'b': 34, 'c': "fame", d: "who"},
{'a': (94, 29), 'b': 3, 'c': "house", d: "cats"},
{'a': (23, 12), 'b': 93, 'c': "imap", d: "stack"},
]
to give
d = {'a': [(23, 48), (94,29), 23,12], 'b': [34, 3, 94],
'c': ["fame", "house", "imap"], 'd': ['who', 'cats', 'stack'] }
code used
for i in l:
d["a"].extend(i.get('a')),
d["b"].extend(i.get('b')),
d["c"].extend(i.get('c')),
d['d'].extend(i.get('d'))
You should initialize d as an empty dict instead, so that you can iterate through l and the key-value pairs to keep appending the values to the sub-list of d at the given keys:
l = [
{'a': (23, 48), 'b': 34, 'c': "fame", 'd': "who"},
{'a': (94, 29), 'b': 3, 'c': "house", 'd': "cats"},
{'a': (23, 12), 'b': 93, 'c': "imap", 'd': "stack"},
]
d = {}
for s in l:
for k, v in s.items():
d.setdefault(k, []).append(v)
d becomes:
{'a': [(23, 48), (94, 29), (23, 12)],
'b': [34, 3, 93],
'c': ['fame', 'house', 'imap'],
'd': ['who', 'cats', 'stack']}
If the sub-dicts in l may contain other keys, you can instead initialize d as a dict of empty lists under the desired keys:
l = [
{'a': (23, 48), 'b': 34, 'c': "fame", 'd': "who"},
{'a': (94, 29), 'b': 3, 'c': "house", 'd': "cats"},
{'a': (23, 12), 'b': 93, 'c': "imap", 'd': "stack"},
{'e': 'choices'}
]
d = {k: [] for k in ('a', 'b', 'c', 'd')}
for s in l:
for k in d:
d[k].append(s.get(k))
in which case d becomes:
{'a': [(23, 48), (94, 29), (23, 12), None],
'b': [34, 3, 93, None],
'c': ['fame', 'house', 'imap', None],
'd': ['who', 'cats', 'stack', None]}
You can use defaultdict as follow since the default value is an empty list (https://docs.python.org/2/library/collections.html#collections.defaultdict)
import collections
d = collections.defaultdict(list)
keys = ['a', 'b', 'c', 'd']
for i in l:
for k in keys:
d[k].append(i[k])
print(d)
Best regard

how do I increase the width of pandastable

I have the following in Python:
from tkinter import Tk, Frame
from pandastable import Table
import pandas as pd
xx = Tk()
xx.state('zoomed')
xx.title('The Sheet')
f = Frame(xx, width=800, height=400, bd=2)
f.place(x=20, y=20)
df = pd.DataFrame([], columns=['a', 'b', 'c', 'd', 'e', 'f'])
df = df.append({'a': 123, 'b': 'asdf ery', 'c': 345.1, 'd': 'qweqwe qweqwe', 'e': 123.2, 'f': 45646.4}, ignore_index=True)
df = df.append({'a': 234, 'b': 'qwersdfg sdfg', 'c': 7234.9, 'd': 'asd asd asdasd asd', 'e': 21.7, 'f': 1123.8}, ignore_index=True)
df = df.append({'a': 456, 'b': 'zxcv xcvb', 'c': 1209.3, 'd': 'zxc zxc zxc zxc zxc zxc', 'e': 1.298, 'f': 10023.6}, ignore_index=True)
pt = Table(f, dataframe=df, showtoolbar=False, showstatusbar=False)
pt.show()
xx.mainloop()
However, no matter how much I increased the Frame width, the displayed table remains the same size. I want to show all the six columns. How is this done?
Try adding this to your code..
1.
f.pack(fill='both',expand=True)
2.
f.pack(fill='x',expand=True) # Will best suit your case
# will expand the frame on x-axis
3.
f.pack(fill='y',expand=True) # Will expand the frame in y axis
Hope this helps

Find Average and Minimum Value from Array Object - Python

I have a data like below,
resultFromCalculation = [{'value40': {'A': 3.1, 'B': 5.62, 'C': 5.99, 'D': 5.06, 'E': 5.09}},
{'value50': {'A': 2.95, 'B': 5.21, 'C': 5.41, 'D': 4.64, 'E': 4.5}},
{'value60': {'A': 2.35, 'B': 4.8, 'C': 4.83, 'D': 4.08, 'E': 3.62}},
{'value70': {'A': 2.95, 'B': 5.21, 'C': 5.41, 'D': 4.64, 'E': 4.5}}]
I want to find average for A to E values for each list. Like,
avgValues = [{'value40':4.97},{'value50':4.41},{'value60':3.99},{'value70':3.99}]
From the above OP I need to find out which one is first least value than others.
FinalResultIs = value60
Using Pandas:
>>> pd.concat([pd.DataFrame(d) for d in resultFromCalculation], axis=1).mean()
value40 4.972
value50 4.542
value60 3.936
value70 4.542
dtype: float64
>>> pd.concat([pd.DataFrame(d) for d in resultFromCalculation], axis=1).mean().argmin()
'value60'
Using simple list comprehension, you can use
avgValues = [{list(d.keys())[0]: sum(list(d.values())[0].values()) / len(list(d.values())[0].values())} for d in resultFromCalculation]
>>> avgValues
[{'value40': 4.9719999999999995},
{'value50': 4.542},
{'value60': 3.936000000000001},
{'value70': 4.542}]
To find the minimum:
>>> min(avgValues, key=lambda e: list(e.values())[0])
{'value60': 3.936000000000001}
Use:
L = [pd.DataFrame(x).mean().to_dict() for x in resultFromCaluclation]
print (L)
[{'value40': 4.9719999999999995}, {'value50': 4.542}, {'value60': 3.936000000000001}, {'value70': 4.542}]

Resources