Normalize the values of nested dictionary into [0,1]
Input dictionary
d = {'PQR':{"LMN":1.345,'PST':1.278,'BQR':2.345,'RMT':9.867},
'HGE':{'VRM':1.765,'TRM':1.567,'FRM':1.456,'DRM':1.678}}
Is there any way to normalize the nested dictionary values in the range [0,1] using this formula
(value - min(x))/(max(x)- min(x))
However, for normalization, min and max values should find in every inner dictionary. Expected Output
output = {'PQR':{"LMN":0.0078006752823378675,'PST':0.0,'BQR':0.12422866457096288,'RMT':1.0},
'HGE':{'VRM':1.0,'TRM':0.3592233009708738,'FRM':0.0,'DRM':0.7184466019417476}}
1 answer
-
answered 2022-05-04 11:07
Kris
You can loop the inner dicts and mutate them accordingly. An example approach below:
d = {'PQR': {"LMN": 1.345, 'PST': 1.278, 'BQR': 2.345, 'LMN': 9.867}, 'HGE': {'VRM': 1.765, 'TRM': 1.567, 'FRM': 1.456, 'DRM': 1.678}} # Find the normalized value fn = lambda value, x_max, x_min: (value - x_min) / (x_max - x_min) # In each inner dict for _d in d.values(): # find min and max values max_x = max(_d.values()) min_x = min(_d.values()) # normalize each value in the dict for k, v in _d.items(): _d[k] = fn(v, max_x, min_x) print(d)
Gives you an output like below:
{'PQR': {'LMN': 1.0, 'PST': 0.0, 'BQR': 0.12422866457096288}, 'HGE': {'VRM': 1.0, 'TRM': 0.3592233009708738, 'FRM': 0.0, 'DRM': 0.7184466019417476}}
do you know?
how many words do you know
See also questions close to this topic
-
Python File Tagging System does not retrieve nested dictionaries in dictionary
I am building a file tagging system using Python. The idea is simple. Given a directory of files (and files within subdirectories), I want to filter them out using a filter input and tag those files with a word or a phrase.
If I got the following contents in my current directory:
data/ budget.xls world_building_budget.txt a.txt b.exe hello_world.dat world_builder.spec
and I execute the following command in the shell:
py -3 tag_tool.py -filter=world -tag="World-Building Tool"
My output will be:
These files were tagged with "World-Building Tool": data/ world_building_budget.txt hello_world.dat world_builder.spec
My current output isn't exactly like this but basically, I am converting all files and files within subdirectories into a single dictionary like this:
def fs_tree_to_dict(path_): file_token = '' for root, dirs, files in os.walk(path_): tree = {d: fs_tree_to_dict(os.path.join(root, d)) for d in dirs} tree.update({f: file_token for f in files}) return tree
Right now, my dictionary looks like this:
key:''
.In the following function, I am turning the empty values
''
into empty lists (to hold my tags):def empty_str_to_list(d): for k,v in d.items(): if v == '': d[k] = [] elif isinstance(v, dict): empty_str_to_list(v)
When I run my entire code, this is my output:
hello_world.dat ['World-Building Tool'] world_builder.spec ['World-Building Tool']
But it does not see
data/world_building_budget.txt
. This is the full dictionary:{'data': {'world_building_budget.txt': []}, 'a.txt': [], 'hello_world.dat': [], 'b.exe': [], 'world_builder.spec': []}
This is my full code:
import os, argparse def fs_tree_to_dict(path_): file_token = '' for root, dirs, files in os.walk(path_): tree = {d: fs_tree_to_dict(os.path.join(root, d)) for d in dirs} tree.update({f: file_token for f in files}) return tree def empty_str_to_list(d): for k, v in d.items(): if v == '': d[k] = [] elif isinstance(v, dict): empty_str_to_list(v) parser = argparse.ArgumentParser(description="Just an example", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("--filter", action="store", help="keyword to filter files") parser.add_argument("--tag", action="store", help="a tag phrase to attach to a file") parser.add_argument("--get_tagged", action="store", help="retrieve files matching an existing tag") args = parser.parse_args() filter = args.filter tag = args.tag get_tagged = args.get_tagged current_dir = os.getcwd() files_dict = fs_tree_to_dict(current_dir) empty_str_to_list(files_dict) for k, v in files_dict.items(): if filter in k: if v == []: v.append(tag) print(k, v) elif isinstance(v, dict): empty_str_to_list(v) if get_tagged in v: print(k, v)
-
Actaully i am working on a project and in it, it is showing no module name pip_internal plz help me for the same. I am using pycharm(conda interpreter
File "C:\Users\pjain\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main return _run_code(code, main_globals, None, File "C:\Users\pjain\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code exec(code, run_globals) File "C:\Users\pjain\AppData\Local\Programs\Python\Python310\Scripts\pip.exe\__main__.py", line 4, in <module> File "C:\Users\pjain\AppData\Local\Programs\Python\Python310\lib\site-packages\pip\_internal\__init__.py", line 4, in <module> from pip_internal.utils import _log
I am using pycharm with conda interpreter.
-
Looping the function if the input is not string
I'm new to python (first of all) I have a homework to do a function about checking if an item exists in a dictionary or not.
inventory = {"apple" : 50, "orange" : 50, "pineapple" : 70, "strawberry" : 30} def check_item(): x = input("Enter the fruit's name: ") if not x.isalpha(): print("Error! You need to type the name of the fruit") elif x in inventory: print("Fruit found:", x) print("Inventory available:", inventory[x],"KG") else: print("Fruit not found") check_item()
I want the function to loop again only if the input written is not string. I've tried to type return Under print("Error! You need to type the name of the fruit") but didn't work. Help
-
VBA: Creating a class property that is an array of dictionaries
In Microsoft Excel VBA I need to create a class that has two properties, "Name" and "Holdings". "Name" is just a string so the code for that is easy. But I need "Holdings" to be a variable length array containing dictionary objects. So this is what I wrote:
Private mName As String Private mHoldings() As Scripting.Dictionary Public Property Let Name(vName As String) mName = vName End Property Public Property Get Name() As String Name = mName End Property Public Property Set Holdings(vHoldings() As Scripting.Dictionary) Set mHoldings = vHoldings End Property Public Property Get Holdings() As Scripting.Dictionary Set Holdings = mHoldings End Property
When I try to compile it gives me this error: "Definitions of property procedures for the same property are inconsistent, or property procedure has an optional parameter, a ParamArray, or an invalide Set final parameter.
What I doing wrong?
-
Map for react-native ( No google map and apple map)
Is there a map that can be used in React-Native?
If so, please upload an example of how to use it.
But again! No Google map and Apple map.
-
Calculation between vectors in nested for loops
I am struggling with an issue concerned with nested for loops and calculation with conditions.
Let's say I have a data frame like this:
df = data.frame("a" = c(2, 3, 3, 4), "b" = c(4, 4, 4, 4), "c" = c(5, 5, 4, 4), "d" = c(3, 4, 4, 2))
With this df, I want to compare each element between vectors with a condition: if the absolute difference between two elements is lower than 2 (so difference of 0 and 1), I'd like to accord 1 in a newly created vector while the absolute difference between two elements is >= 2, I'd like to append 0.
For example, for a calculation between the vector "a" and the other vectors "b", "c", "d", I want this result: 0 0 1. The first 0 is accorded based on the difference of 2 between a1 and b1; the second 0 is based on the difference of 3 between a1 and c1; the 1 is based on the difference of a1 and d1. So I tried to make a nested for loop to applicate the same itinerary to the elements in the following rows as well.
So my first trial was like this:
list_all = list(df$a, df$b, df$c, df$d) v0<-c() for (i in list_all) for (j in list_all) if (i != j) { if(abs(i-j)<2) { v0<-c(v0, 1) } else { v0<-append(v0, 0) }} else { next}
The result is like this :
v0 [1] 0 0 1 0 1 1 0 1 0 1 1 0
But it seems that the calculation has been made only among the first elements but not among the following elements.
So my second trial was like this:
list = list(df$b, df$c, df$d) v1<-c() for (i in df$a){ for (j in list){ if(abs(i-j)<2) { v1<-append(v1, 1) } else { v1<-append(v1, 0) } } } v1 v1 [1] 0 0 1 1 0 1 1 0 1 1 1 1
It seems like the calculations were made between all elements of df$a and ONLY the first elements of the others. So this is not what I needed, either.
When I put df$b instead of list in the nested for loop, the result is even more messy.
v2<-c() for (i in df$a){ for (j in df$b){ if(abs(i-j)<2) { v2<-append(v2, 1) } else { v2<-append(v2, 0) } } } v2 [1] 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
It seems like the calculation has not been made between the corresponding elements (in the same rows), but between all vectors regardless of the place.
Could anyone tell me how to fix the problem? I don't understand why the nested for loop works only for the first elements.
Thank you in advance.
-
My for-loop that outputs a chessboard only works with even numbers, WHY?
Write a program that creates a string that represents an 8×8 grid, using newline characters to separate lines. At each position of the grid there is either a space or a "#" character. The characters should form a chessboard.
/* Passing this string to console.log should show something like this: # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # When you have a program that generates this pattern, define a binding size = 8 and change the program so that it works for any size, */
outputting a grid of the given width and height.
Here's my answer:
let countPosition = 0, countLine = 0, size = 8, output = ''; for (let i =0; i < size; i++) { for (let j = 0; j < size; j++) { if (countLine % 2 == 0) { if (countPosition % 2 == 0) { output += " "; } else { output += "#"; } } else { if (countPosition % 2 == 0) { output += "#"; } else { output += ' '; } } countPosition += 1; } countLine += 1; output += '\n'; } console.log(output); console.log(countLine);
My problem is that my code only works with even numbers!!!!! WHY???!! I have been stuck with this for a while I don't understand what's wrong with the code. It looks so logical why would it not work with odd numbers why? Any intellectual out there please explain this weird quirk.
This is a problem from Eloquent JavaScript: (https://eloquentjavascript.net/02_program_structure.html#i_swb9JBtSQQ)
(Edit: sorry for the weird formatting above, I couldn't get the chessboard to look okay without writing it as if it were a code snippet)
-
Nested for loop through json object array does not work
I need to build a new array based on json array (Context) bellow. Unfortunately I never reach the outer Loop after passing by first run. Is there any mistake in code? How can I solve this issue?
Thank you for help.
Context:
"rfqBp": [ { "rfqBpId": 1041650, "Contact": [ { "ID": 1000014, "SelectedContact": true }, { "ID": 1002411, "SelectedContact": true }, { "ID": 1016727, "SelectedContact": true }, { "ID": 1017452, "SelectedContact": true } ], }, { "rfqBpId": 1052326, "Contact": [ { "ID": 1016236, "SelectedContact": true }, { "ID": 1019563, "SelectedContact": true } ], }, { "rfqBpId": 1056632, "Contact": [ { "ID": -1, "SelectedContact": false } ], }, { "rfqBpId": 1056637, "Contact": [ { "ID": 1019875, "SelectedContact": true } ], } ],
script:
$scope.SelectedContacts = function() { //function starts by click on checkbox in html let selectedContactList = []; let finalList = []; $scope.Context.Output = []; for (let i = 0; i <= $scope.Context.rfqBp.length; i++) { for (let j = 0; j <= $scope.Context.rfqBp[i].Contact.length; j++) { if ($scope.Context.rfqBp[i].Contact[j].SelectedContact === true) { selectedContactList = { "ID": $scope.Context.rfqBp[i].Contact[j].ID }; finalList.push(selectedContactList); } else if ($scope.Context.rfqBp[i].Contact[j].SelectedContact !== true) { continue; } $scope.Context.Output = finalList; //Output works but just for rfqBp[1] }; }; $scope.Context.Output = finalList; //this part never reached };
Output:
"Output": [ { "ID": 1000014 }, { "ID": 1016727 }, { "ID": 1017452 } ]
I try to get following:
"Output": [ { "ID": 1000014 }, { "ID": 1016727 }, { "ID": 1017452 }, { "ID": 1016236 }, { "ID": 1019563 }, { "ID": 1019875 } ]
-
How do I normalize data that includes factor?
Please help me understand how to ensure I correctly handle this normalization. Suppose one has a dataset containing multiple classes, including:
- character
- Factor
- integer
- numeric
Re. 1 (character): let's say this is a column of locations: Dallas, Trenton, and Atlanta. To prepare for normalization, I make Dallas=1, Trenton=2, and Atlanta=3, thus converting this column to integer.
Re. 2 (factor): let's say this is a logical column stating whether salesperson is active: 1=yes, 0=no.
Re. 3a (integer): this column identifies salesperson rank: 1, 2, or 3.
Re. 3b (integer): this column tells how many people are on salespersons' teams: 1, 2, 3, 4...
Re. 4 (numeric): this column discloses sales totals, e.g., 50,000, 100strong text,000, etc.
My two questions I want to use min-max normalization, but I have two questions:
First, does it matter that I have various
factor
andinteger
classes in addition tonumeric
? I do not want to undermine a regression model by getting this wrong.And second, my aim is to perform min-max normalization using
min_max_norm <- function(x){ (x - min(x)) / (max(x) - min(x)) }
Is this appropriate with the data classes I have?
- Any ideas on how this would look normalized?