Ich habe 2 Dimensionen:
dimensions = ('product', 'place')
Und 2 Metriken:
metrics = ('METRIC_1', 'METRIC_2')
Eingang ist die folgende Liste von dicts mit Dimensionen und Kennzahlen
input = [
{'product': 'eggs', 'place': 'fridge', 'METRIC_1': 1, 'METRIC_2': 2},
{'product': 'eggs', 'place': 'table', 'METRIC_1': 3, 'METRIC_2': 1},
{'product': 'ham', 'place': 'fridge', 'METRIC_1': 1, 'METRIC_2': 2},
{'product': 'ham', 'place': 'table', 'METRIC_1': 3, 'METRIC_2': 5},
]
Für jede Dimension und jede Kombination von Dimensionen möchte ich "_all_" -Wert erhalten, wo Metriken zusammengefasst werden (oder eine andere Aggregationsmethode angewendet wird)).Python. Berechnen Dimension Summen für die Liste der Wörterbücher
Erwartetes Ergebnis:
result = [
{'product': '_all_', 'place': 'fridge', 'METRIC_1': 2, 'METRIC_2': 4},
{'product': '_all_', 'place': 'table', 'METRIC_1': 6, 'METRIC_2': 6},
{'product': 'eggs', 'place': '_all_', 'METRIC_1': 4, 'METRIC_2': 3},
{'product': 'ham', 'place': '_all_', 'METRIC_1': 4, 'METRIC_2': 7},
{'product': '_all_', 'place': '_all_', 'METRIC_1': 8, 'METRIC_2': 8},
]
Betrachten Sie diese Anzahl von Dimensionen und Kennzahlen ist flexibel. Wäre dankbar, wenn die Antwort eine Funktion mit der folgenden Signatur:
calc_totals(input_list, dimensions_list, {'metric_1': 'sum', 'metric_2': 'sum'}):
pass
Mein Versuch folgt, scheint aber zu kompliziert und nicht sicher, ob es richtig ist:
from operator import itemgetter
from itertools import groupby, combinations, chain
def powerset(iterable):
xs = list(iterable)
return chain.from_iterable(combinations(xs, n) for n in range(len(xs)+1))
def calc_totals(input, dimensions):
totals = []
dim_combs = list(powerset(dimensions))[1:-1]
for dim_comb in dim_combs:
current_dims = dimensions.difference(set(dim_comb))
grouper = itemgetter(*current_dims)
for key, group in groupby(sorted(input, key=grouper), grouper):
temp_dict = dict(zip(list(current_dims), [key]))
temp_dict['METRIC_1'] = 0
temp_dict['METRIC_2'] = 0
for item in group:
temp_dict['METRIC_1'] += item['METRIC_1']
temp_dict['METRIC_2'] += item['METRIC_2']
for dim in dim_comb:
temp_dict[dim] = '_all_'
totals.append(temp_dict)
return totals