简体   繁体   中英

How to sum all the values that belong to the same key?

I'm pulling data from the database and assuming i have something like this:

    Product Name    Quantity
    a               3
    a               5
    b               2
    c               7

I want to sum the Quantity based on Product name, so this is what i want:

    product = {'a':8, 'b':2, 'c':7 }

Here's what I'm trying to do after fetching the data from the database:

    for row in result:
       product[row['product_name']] += row['quantity']

but this will give me: 'a'=5 only, not 8.

Option 1: pandas

This is one way, assuming you begin with a pandas dataframe df . This solution has O(n log n) complexity.

product = df.groupby('Product Name')['Quantity'].sum().to_dict()

# {'a': 8, 'b': 2, 'c': 7}

The idea is you can perform a groupby operation, which produces a series indexed by "Product Name". Then use the to_dict() method to convert to a dictionary.

Option 2: collections.Counter

If you begin with a list or iterator of results, and wish to use a for loop, you can use collections.Counter for O(n) complexity.

from collections import Counter

result = [['a', 3],
          ['a', 5],
          ['b', 2],
          ['c', 7]]

product = Counter()

for row in result:
    product[row[0]] += row[1]

print(product)
# Counter({'a': 8, 'c': 7, 'b': 2})

Option 3: itertools.groupby

You can also use a dictionary comprehension with itertools.groupby . This requires sorting beforehand.

from itertools import groupby

res = {i: sum(list(zip(*j))[1]) for i, j in groupby(sorted(result), key=lambda x: x[0])}

# {'a': 8, 'b': 2, 'c': 7}

If you insist on using loops, you can do this:

# fake data to make the script runnable
result = [
  {'product_name': 'a', 'quantity': 3},
  {'product_name': 'a', 'quantity': 5},
  {'product_name': 'b', 'quantity': 2},
  {'product_name': 'c', 'quantity': 7}
]

# solution with defaultdict and loops
from collections import defaultdict

d = defaultdict(int)
for row in result:
  d[row['product_name']] += row['quantity']

print(dict(d))

The output:

{'a': 8, 'b': 2, 'c': 7}

Use tuple to store the result.

Edit:


Not clear if the data mentioned is really a dataframe.

If yes then li = [tuple(x) for x in df.to_records(index=False)]


li = [('a', 3), ('a', 5), ('b', 2), ('c', 7)]
d = dict()
for key, val in li:
    val_old = 0
    if key in d:
        val_old = d[key]
    d[key] = val + val_old
print(d)

Output

{'a': 8, 'b': 2, 'c': 7}

Since you mention pandas

df.set_index('ProductName').Quantity.sum(level=0).to_dict()
Out[20]: {'a': 8, 'b': 2, 'c': 7}

从product左联接QUANTITY GROUP BY产品名中选择product_name,SUM(数量)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM