I've got a defaultdict with a nested dictionary from which I'm trying to get the sum of the values. But I've been struggling to find a way to do this.
In the example below, I'm trying to count all the count values:
from collections import defaultdict
x = defaultdict(dict)
x['test1']['count'] = 14
x['test4']['count'] = 14
x['test2']['count'] = 14
x['test3']['count'] = 14
print x
""" methods I've tried """
# print x.values()
# print sum(x for y in x.values() for x in y['count'].iteritems())
# print sum(x.itervalues())
The methods above that I've tried (in many different variations) didn't provide the desired results.
Any clues or assistance as to where I may be in error?
If you have to caluculate sum of just 'count' key, you may do:
>>> sum(y['count'] for y in x.values())
56
If there is a possibility of having other keys as well (apart from 'count'), and you want to calculate sum of all the values, then you have to do:
>>> sum(z for y in x.values() for z in y.values())
56
# OR,
# import itertools
# sum(itertools.chain(*[y.values() for y in x.values()]))
Just sum(x[k]['count'] for k in x) should work.
If you want to sum the values of all sub dictionaries, sum twice:
>>> sum(sum(y.values()) for y in x.values())
56
Related
values = ['random word1', 20, 'random word2', 54]
values = list(map(list,zip(values[::2], values[1::2])))
print(values)
[['random word1', 20], ['random word2', 54]]
Now I want to fetch values
like this:
if ‘random word2’ in values:
get the value associated with random word 2 which is in this case 54.
Note: string words and values are random.
How can I do that?
I need to fetch the correct value.
I think a dictionary over a list is the way to go
d = dict(zip(values[::2], values[1::2]))
print(d['random word1']) # -> 20
try:
value = values[values.index("random words2") + 1]
except ValueError:
value = None
Or, if you need to fecth more values, convert your list to a dictionary and then use the get method. Even for 2 retrievals this will already be more efficient, algorithmically wise:
# make N 2-tuples treating the odd-positioned elements as keys and
# even ones as values, and call the dict constructor with that:
v = dict([i:i+2] for i in range(0, len(values), 2))
v.get("random word2")
I created a list of RGB values for an image (let's say it's 3D_image, composed of 3D_image_slice). I want to extract the unique RGB values from it, but I'm running into problems.
rgb_values_unique = []
for 3D_image_slice in 3D_image:
for y in range(3D_image_slice.shape[0]):
for x in range(3D_image_slice.shape[1]):
if 3D_image_slice[y, x] not in rgb_values_unique:
rgb_values_unique.append(3D_image_slice[y, x])
I was thinking of using np.unique, but that doesn't apply to lists. Is there another way to find unique values within a list?
You have a couple of easy options; one is to create a unique list of strings (I don't love this since it changes the datatype, but it's look something like this):
rgb_values_unique = set()
for 3D_image_slice in 3D_image:
for y in range(3D_image_slice.shape[0]):
for x in range(3D_image_slice.shape[1]):
rgb_values_unique.add("-".join(3D_image_slice[y, x])
print(rgb_values_unique)
# {"r0-g0-b0", "r1-g1-b1", ...}
#which you could convert back into numbers like this:
result = [[int(j) for j in i.split("-")] for i in rgb_values_unique]
What I'd probably do is leverage the uniqueness of a dictionary:
rgb_values_unique = {}
for 3D_image_slice in 3D_image:
for y in range(3D_image_slice.shape[0]):
for x in range(3D_image_slice.shape[1]):
r,g,b = 3D_image_slice[y, x]
rgb_values_unique .setdefault(r, {}).setdefault(g, []).append(b)
print(rgb_values_unique)
# {r0: {g0: [b0, b1, b2]}, {g1: ...
Which you can then turn into a unique listing as follows:
result = [(r,g,b) for r,v in rgb_values_unique.items() for g, b_list in v.items() for b in b_list]
u can use sets to save only unique values:
rgb_values_unique = {}
for 3D_image_slice in 3D_image:
for y in range(3D_image_slice.shape[0]):
for x in range(3D_image_slice.shape[1]):
rgb_values_unique |= 3D_image_slice[y, x]
I currently have the code below working fine:
Can someone help me solve the collision created from having two keys with the same number in the dictionary?
I tried multiple approach (not listed here) to try create an array to handle it but my approaches are still unsuccessful.
I am using #python3.7
def find_key(dic1, n):
'''
Return the key '3' from the dict
below.
'''
d = {}
for x, y in dic1.items():
# swap keys and values
# and update the result to 'd'
d[y] = x
try:
if n in d:
return d[y]
except Exception as e:
return (e)
dic1 = {'james':2,'david':3}
# Case to test that return ‘collision’
# comment 'dic1' above and replace it by
# dic1 below to create a 'collision'
# dic1 = {'james':2,'david':3, 'sandra':3}
n = 3
print(find_key(dic1,n))
Any help would be much appreciated.
You know there should be multiple returns, so plan for that in advance.
def find_keys_for_value(d, value):
for k, v in d.items():
if v == value:
yield k
data = {'james': 2, 'david': 3, 'sandra':3}
for result in find_keys_for_value(data, 3):
print (result)
You can use a defaultdict:
from collections import defaultdict
def find_key(dct, n):
dd = defaultdict(list)
for x, y in dct.items():
dd[y].append(x)
return dd[n]
dic1 = {'james':2, 'david':3, 'sandra':3}
print(find_key(dic1, 3))
print(find_key(dic1, 2))
print(find_key(dic1, 1))
Output:
['david', 'sandra']
['james']
[]
Building a defaultdict from all keys and values is only justified if you will repeatedly search for keys of the same dict given different values, though. Otherwise, the approach of Kenny Ostrom is preferrable. In any case, the above makes little sense if left as it stands.
If you are not at ease with generators and yield, here is the approach of Kenny Ostrom translated to lists (less efficient than generators, better than the above for one-shot searches):
def find_key(dct, n):
return [x for x, y in dct.items() if y == n]
The output is the same as above.
I have a dataframe having categorical variables. I want to convert them to the numerical using the following logic:
I have 2 lists one contains the distinct categorical values in the column and the second list contains the values for each category. Now i need to map these values in place of those categorical values.
For Eg:
List_A = ['A','B','C','D','E']
List_B = [3,2,1,1,2]
I need to replace A with 3, B with 2, C and D with 1 and E with 2.
Is there any way to do this in Python.
I can do this by applying multiple for loops but I am looking for some easier way or some direct function if there is any.
Any help is very much appreciated, Thanks in Advance.
Create a mapping dict
List_A = ['A','B','C','D','E',]
List_B = [3,2,1,1,2]
d=dict(zip(List_A, List_B))
new_list=['A','B','C','D','E','A','B']
new_mapped_list=[d[v] for v in new_list if v in d]
new_mapped_list
Or define a function and use map
List_A = ['A','B','C','D','E',]
List_B = [3,2,1,1,2]
d=dict(zip(List_A, List_B))
def mapper(value):
if value in d:
return d[value]
return None
new_list=['A','B','C','D','E','A','B']
map(mapper,new_list)
Suppose df is your data frame and "Category" is the name of the column holding your categories:
df[df.Category == "A"] = 3,2, 1, 1, 2
df[(df.Category == "B") | (df.Category == "E") ] = 2
df[(df.Category == "C") | (df.Category == "D") ] = 1
If you only need to replace values in one list with the values of other and the structure is like the one you say. Two list, same lenght and same position, then you only need this:
list_a = []
list_a = list_b
A more convoluted solution would be like this, with a function that will create a dictionary that you can use on other lists:
# we make a function
def convert_list(ls_a,ls_b):
dic_new = {}
for letter,number in zip(ls_a,ls_b):
dic_new[letter] = number
return dic_new
This will make a dictionary with the combinations you need. You pass the two list, then you can use that dictionary on other list:
List_A = ['A','B','C','D','E']
List_B = [3,2,1,1,2]
dic_new = convert_list(ls_a, ls_b)
other_list = ['a','b','c','d']
for _ in other_list:
print(dic_new[_.upper()])
# prints
3
2
1
1
cheers
You could use a solution from machine learning scikit-learn module.
OneHotEncoder
LabelEncoder
http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html
The pandas "hard" way:
https://stackoverflow.com/a/29330853/9799449
I have a dictionary with a tuple of 5 values as a key. For example:
D[i,j,k,g,h] = value.
Now i need to process all elements with a certain partial key pair (i1,g1):
I need now for each pair (i1,g1) all values that have i == i1 and g == g1 in the full key.
What is an pythonic and efficient way to retrieve this, knowing that i need the elements for all pairs and each full key belongs to exactly one partial key?
Is there a more appropriate data structure than dictionaries?
One reference implementation is this:
results = {}
for i in I:
for g in G:
results[i,g] = []
for i,j,k,g,h in D:
if i1 == i and g1 == g:
results[i,g].append(D[i,j,k,g,h])
Assuming you know all the valid values for the different indices you can get all possible keys using itertools.product:
import itertools
I = [3,6,9]
J = range(10)
K = "abcde"
G = ["first","second"]
H = range(10,20)
for tup in itertools.product(I,J,K,G,H):
my_dict[tup] = 0
To restrict the indices generated just put a limit on one / several of the indices that gets generated, for instance all of the keys where i = 6 would be:
itertools.product((6,), J,K,G,H)
A function to let you specify you want all the indices where i==6 and g =="first" would look like this:
def partial_indices(i_vals=I, j_vals=J, k_vals=K, g_vals = G, h_vals = H):
return itertools.product(i_vals, j_vals, k_vals, g_vals, h_vals)
partial_indices(i_vals=(6,), g_vals=("first",))
Or assuming that not all of these are present in the dictionary you can also pass the dictionary as an argument and check for membership before generating the keys:
def items_with_partial_indices(d, i_vals=I, j_vals=J, k_vals=K, g_vals = G, h_vals = H):
for tup in itertools.product(i_vals, j_vals, k_vals, g_vals, h_vals):
try:
yield tup, d[tup]
except KeyError:
pass
for k,v in D.iteritems():
if i in k and p in k:
print v