0

それぞれ 2 つの金額を持つ一連のカテゴリで構成されるデータがあります。例えば、{'cat':'red', 'a':1, 'b':2}, {'cat':'red', 'a':3, 'b':3}, {'cat':'blue', 'a':1, 'b':3}

カテゴリごとに、2 つの金額の現在の合計を保持したいと考えています。結果は{'cat':'red', 'a':4, 'b':5}, {'cat':'blue', 'a':1, 'b':3}

以下よりもPython的な方法はありますか?

totals = {}
for item in data:
    if item['cat'] in totals:
        totals[item['cat']]['a'] += item['a']
        totals[item['cat']]['b'] += item['b']
    else:
        totals[item['cat']] = {'a':item['a'], 'b':item['b']}
4

3 に答える 3

2

データ構造は、cat値をキーにして辞書に実際に移動する必要があります。collections.defaultdict()とを使用しcollections.Counter()て値を追跡し、合計を簡単にします。

from collections import defaultdict, Counter

totals = defaultdict(Counter)

for item in data:
    cat = item.pop('cat')
    totals[cat] += Counter(item)

デモ:

>>> from collections import defaultdict, Counter
>>> data = {'cat':'red', 'a':1, 'b':2}, {'cat':'red', 'a':3, 'b':3}, {'cat':'blue', 'a':1, 'b':3}
>>> totals = defaultdict(Counter)
>>> for item in data:
...     cat = item.pop('cat')
...     totals[cat] += Counter(item)
... 
>>> totals
defaultdict(<class 'collections.Counter'>, {'blue': Counter({'b': 3, 'a': 1}), 'red': Counter({'b': 5, 'a': 4})})
>>> totals['blue']
Counter({'b': 3, 'a': 1})
>>> totals['red']
Counter({'b': 5, 'a': 4})

それでも同じ形式の一連の辞書が必要な場合は、上記のカウンターの辞書を再び「プレーンな」辞書に戻すことができます。

output = []
for cat, counts in totals.iteritems():
    item = {'cat': cat}
    item.update(counts)
    output.append(item)

その結果:

>>> output
[{'a': 1, 'b': 3, 'cat': 'blue'}, {'a': 4, 'b': 5, 'cat': 'red'}]
于 2013-09-07T08:28:46.657 に答える
1

dict.setdefaultcollections.counterを見てください。setdefault を使用した可能な解決策:

totals = {}
for item in data:
    d = totals.setdefault(item['cat'],  {'a':0, 'b':0})
    d['a'] += item['a']
    d['b'] += item['b']

結果でtotal = {'blue': {'a': 1, 'b': 3}, 'red': {'a': 4, 'b': 5}}'cat'これには、予想される回答のようなエントリがないことに注意してください。代わりに、結果のディクショナリのキーとして色が直接使用されます。

を使用した例については、Martijn の回答を参照してくださいCounter

于 2013-09-07T08:23:47.110 に答える
0

collections.Countercollections.defaultdictクラスの組み合わせに基づいて、一時的な複合データ構造にデータを収集します。このデータ構造のキーは猫の色になり、それぞれに関連付けられてCounter、各色の猫の合計を保持します。それを作るということはdefaultdict、その色に出会うのが初めてかどうかを心配する必要がないということです。

これにより、作成時に必要な値の合計が実行され、後で必要な出力シーケンスに変換するのがかなり簡単になります。

from collections import Counter, defaultdict

data = ({'cat':'red', 'a':1, 'b':2},
        {'cat':'red', 'a':3, 'b':3},
        {'cat':'blue', 'a':1, 'b':3})

cat_totals = defaultdict(Counter)  # hybrid data structure
for entry in data:
    cat_totals[entry['cat']].update({k:v for k,v in entry.iteritems() 
                                            if k != 'cat'})

results = tuple(dict([('cat', color)] + cat_totals[color].items())
            for color in cat_totals)

print results # ({'a': 1, 'b': 3, 'cat': 'blue'}, {'a': 4, 'b': 5, 'cat': 'red'})
于 2013-09-07T12:34:53.963 に答える