ricehound
ricehound

Reputation: 3

How to merge two dictionaries together and add their values if the keys are the same and the values are arrays?

I have two dictionaries and the keys are the same but the values are arrays, please see below:

print(helix1_coords) 'A-85-CA': [array([ 50.393, -20.181, 12.316], dtype=float32)], 'A-86-CA': [array([ 52.819, -18.757, 14.976], dtype=float32)]}...'

print(helix2_coords) 'A-175-CA': [array([ 31.465, -1.023, -23.405], dtype=float32)], 'A-176-CA': [array([ 29.751, -2.69 , -26.312], dtype=float32)]}...'

How do I add these two dictionaries together to get something like this:

print(avg_coords) 'A-85-CA': [array([ 81.858, -21.204, -5.5445], dtype=float32)], 'A-86-CA': [array([ 82.57, -21.447, -11.336], dtype=float32)]}...'

^ the keys are the same as helix1_coords, but the values are combined (I have added 50.393 + 31.465 for example)

I would then also like to divide each value by 2, so the final dictionary should look like this:

print(avg_coords) 'A-85-CA': [array([ 40.928, -10.602, 12.316], dtype=float32)], 'A-86-CA': [array([ 41.285,-10.7235, -5.668], dtype=float32)]}...'

Some things I tried:

avg_coords = {key: np.add(helix1_coords.values(), helix2_coords.values()) for key in helix1_coords}

^ This gave me a dictionary where all of the values were the same (the last value of helix1_coords)

avg_coords = {key: np.concatenate((helix1_coords.get(key, np.array([])), helix2_coords.get(key, np.array([])))) for key in set(helix1_coords.keys()).union(set(helix2_coords.keys()))}

^ This was suggested by another question but I got this error:

ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 2 dimension(s)

Please help!

Upvotes: 0

Views: 74

Answers (1)

Ricc
Ricc

Reputation: 26

You can check the zip function, it helps you to iterate in parallel. A quick example:

>>> l1 = [1,2,3,4]
>>> l2 = [4,3,2,1]
>>> for v1, v2 in zip(l1, l2):
        print(v1,v2)
1 4
2 3
3 2
4 1

In your specific case you can make a first zip with dict1 keys, dict1 values and dict2 values. Then you can iterate over the 2 lists with another zip and sum the elements together and divide by 2.

for k, v1, v2 in zip(helix1_coords, helix1_coords.values(), helix2_coords.values()):
    # list comprehension to create final list with the average value for every element
    avg_coords[k] = [(e1+e2)/2 for e1, e2 in zip(v1, v2)]

In one line you can use this, but it's less readable:

avg_coords = {k: np.array([(e1+e2)/2 for e1, e2 in zip(v1, v2)]) for k, v1, v2 in zip(helix1_coords, helix1_coords.values(), helix2_coords.values())}

Upvotes: 1

Related Questions