Source code for materia_epd.metrics.averaging

from materia_epd.core.utils import to_float


[docs] def average_impacts(impacts_list, decimals=6) -> dict[str, dict[str, float | None]]: """Calculate average impacts from a list of impact dictionaries. Returns a dict of the form: { "indicator_name": { "module_name": value, ... }, ... } """ sums: dict[str, dict[str, float]] = {} counts: dict[str, dict[str, int]] = {} for impacts in impacts_list: for item in impacts: name = item.get("name") values = item.get("values", {}) if not name: continue if name not in sums: sums[name] = {} counts[name] = {} for stage, value in values.items(): if isinstance(value, (int, float)) and not isinstance(value, bool): sums[name][stage] = sums[name].get(stage, 0.0) + to_float(value) counts[name][stage] = counts[name].get(stage, 0) + 1 return { name: { stage: ( round(sums[name][stage] / counts[name][stage], decimals) if counts[name][stage] > 0 else None ) for stage in sums[name] } for name in sums }
[docs] def market_weighted_impacts( market_shares: dict[str, float], results_by_country: dict[str, dict[str, dict[str, float | None]]], ) -> dict[str, dict[str, float]]: """Return market-share weighted averages per indicator and module.""" return { ind: { mod: sum( market_shares[c] * results_by_country[c][ind].get(mod, 0.0) for c in market_shares if c in results_by_country and ind in results_by_country[c] ) / sum( market_shares[c] for c in market_shares if c in results_by_country and ind in results_by_country[c] ) for mod in { m for c in market_shares if c in results_by_country and ind in results_by_country[c] for m in results_by_country[c][ind] } } for ind in { ind for country_results in results_by_country.values() for ind in country_results } }
[docs] def average_material_properties(epds: list, decimals: int = 6) -> dict: """Compute average of numeric Material properties from EPDs.""" sums, counts = {}, {} for epd in epds: mat = getattr(epd, "material", None) for key, value in mat.to_dict().items(): if isinstance(value, (int, float)) and not isinstance(value, bool): sums[key] = sums.get(key, 0.0) + value counts[key] = counts.get(key, 0) + 1 return { key: round(sums[key] / counts[key], decimals) if counts[key] > 0 else None for key in sums }