2

I have this df:

import pandas as pd
a = [1,1,1,2,2,3,3,3,3,4,4,5,5,5]
b = ["pi","pi","k","J","pi","pi","k","k","J","pi","k","pi","k","pi"]
bin0 = [0,0,0,1,0,0,1,0,0,0,1,1,0,0]
bin1 = [1,1,1,0,1,0,0,1,1,0,0,0,1,0]
bin2 = [0,0,0,0,0,1,0,0,0,1,0,0,0,1]

df_test = pd.DataFrame({"a": a, "b": b,"bin0": bin0,"bin1": bin1,"bin2": 
bin2})

Like this:

    a   b  bin0  bin1  bin2
0   1  pi     0     1     0
1   1  pi     0     1     0
2   1   k     0     1     0
3   2   J     1     0     0
...
12  5   k     0     1     0
13  5  pi     0     0     1

Then I want to create dictionaries from this df and sum over those dictionaries if they have the same key:

from collections import Counter

thismodule = sys.modules[__name__]

df1 = df_test.groupby(['a', 'b']).agg({'b':'size', 'bin0':'sum', 
'bin1':'sum', 'bin2':'sum'}).rename(columns={'b': 'cant', 'bin0': 'b0', 
'bin1': 'b1', 'bin2': 'b2'}).reset_index(drop = False)


for evt in df1.a.unique():
    name1 = 'dict_'+str(evt)
    name2 = 'col_'+str(evt)
    df_ = df1
    df_ = df_[df_.a==evt].drop('a', 1).set_index('b').to_dict('index')
    setattr(thismodule, name1, df_)
    setattr(thismodule, name2, col_)  

Obtaining, for example:

df_1 = {'k': {'cant': 1, 'b0': 0, 'b1': 1, 'b2': 0}, 'pi': {'cant': 2, 
'b0': 0, 'b1': 2, 'b2': 0}}

col_1 = Counter({'k': {'cant': 1, 'b0': 0, 'b1': 1, 'b2': 0}, 'pi': 
{'cant': 2, 'b0': 1, 'b1': 0, 'b2': 1}})

Finally, when I want to sum over the values of the dictionaries which have the same key I get an error:

col_1 = eval("col_1")
col_2 = eval("col_2")

sumdict = col_1 +col_2
print(sumdict)

The error is:

newcount = count + other[elem]

TypeError: unsupported operand type(s) for +: 'dict' and 'dict'
Laura
  • 1,192
  • 2
  • 18
  • 36
  • Laura, can you add an example of the output. Also, your code those not define col_ objects. – Jorge Feb 17 '19 at 12:56
  • also, in the example you cited in one of your comments below, (https://stackoverflow.com/questions/19882641/sum-value-of-two-different-dictionaries-which-is-having-same-key), it seems they that the same keys, while you have different keys and your dictionary is also nested compared to the dictionary in the other question. – Jorge Feb 17 '19 at 12:59

3 Answers3

1

You're going a lot of crazy things here I think are probably unnecessary and I'd really advise against (eval, setattr), but to answer just your question about summing the values of two counters with shared keys:

from collections import Counter
cx = Counter(x)
cy = Counter(y)

totals = {k:cx.get(k,0) + cy.get(k,0) for k in (set(cx) | set(cy))}
print(totals)

You take the union of both dictionary keys, iterate over it, and use the Counter.get(key, default) method to get the value of the associated key and provide a fallback default if it doesn't exist.

This is a dictionary comprehension but you could also do:

for k in (set(cx) | set(cy)):
    total = cx.get(k,0) + cy.get(k,0)
    print(k, total)

For example, using data built with:

from random import choice
x = [choice("abcdefg") for _ in range(100)]
y = [choice("abcdefg") for _ in range(100)]
y.extend(["z"] * 3)
jedwards
  • 29,432
  • 3
  • 65
  • 92
  • Thanks! It would be very useful for me to know what is the best way to deal with this problem, although it is difficult to explain through this channel! Could you tell me why this solution does not work for me? https://stackoverflow.com/questions/19882641/sum-value-of-two-different-dictionaries-which-is-having-same-key – Laura Feb 16 '19 at 21:24
  • @Laura it's hard to say without knowing more, I'd try to boil your question down to a [MVCE](https://stackoverflow.com/help/mcve) and either edit the question or create a new one with only the details necessary to reproduce the error. The code I posted will work for two counters, so if you're having an issue still we'll need to know what it is, in order to help -- preferably with only the details necessary to reproduce it. – jedwards Feb 16 '19 at 21:31
1

Isn't it this what you want to achieve:

df_test.groupby(['a', 'b']).sum().reset_index().groupby('a').sum()

    bin0    bin1    bin2
a           
1   0   3   0
2   1   1   0
3   1   2   1
4   1   0   1
5   1   1   1
Jorge
  • 2,181
  • 1
  • 19
  • 30
0

Try to use update() method of dict https://www.tutorialspoint.com/python/dictionary_update.htm

count.update(other[elem])

balderman
  • 22,927
  • 7
  • 34
  • 52
  • This method does not apply in this case. – Laura Feb 16 '19 at 20:56
  • Can you please explain why it does not apply when you you you try to merge two dicts like you do in ‘count + other’ – balderman Feb 16 '19 at 21:07
  • Yes, of course: because I don't want to update the dictionaries with the last value. I want to sum over the values which share the same key in the different dictionaries. – Laura Feb 16 '19 at 21:32
  • Got it. See jedwards's above. His code is what you are looking for. – balderman Feb 16 '19 at 21:41