Sum values of dynamically created dictionaries using Counter from collections

烈酒焚心 提交于 2020-01-04 05:14:10

问题


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'

回答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



回答2:


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)



回答3:


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

count.update(other[elem])



来源:https://stackoverflow.com/questions/54727463/sum-values-of-dynamically-created-dictionaries-using-counter-from-collections

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!