I am trying to use LCA.to_dataframe to export LCI for specific activites. Previously I used the matrix_label and cutoff parameters; however, this doesn't seem to work for me anymore, and I am wondering if I am not using it correctly.
The code that I've tried (bw2calc version is (1.8.2)
import bw2calc as bc
import bw2data as bd
ptint(bc.__version__)
eidb = bd.Database("ecoinvent 3.5 cutoff")
# random activity
random_act = eidb.random()
funct_unit = {random_act:1}
# lca, lci
lca = bc.LCA(funct_unit, ('IPCC 2021', 'climate change', 'global warming potential (GWP100)'))
lca.lci()
lca.lcia()
lca.to_dataframe(matrix_label = "inventory", cutoff = None)
The error message was:
LCA.to_dataframe() got an unexpected keyword argument 'matrix_label'
Is there a way to get the inventory dataframe besides calling lca.inventory
and convert the inventory matrix to dataframe myself?
Thanks in advance!
Brightway2 doesn't support matrix_label
, this is a new feature added in 2.5. But we can pretty easily write a function to generate a DataFrame
in the form you want:
import bw2data as bd
import pandas as pd
import numpy as np
from scipy.sparse import spmatrix
from typing import Callable, Optional
from numbers import Number
def to_dataframe(
matrix: spmatrix,
reverse_row: dict,
reverse_col: dict,
obj_lookup: Callable = lambda x: bd.get_activity(x),
cutoff: Optional[Number] = 0.01,
fields: list[str] = ['name', 'location', 'unit']
):
matrix = matrix.tocoo()
elements = np.vstack([matrix.data, matrix.row, matrix.col]).T
order = np.argsort(np.abs(matrix.data))[::-1]
elements = elements[order, :]
if cutoff:
assert cutoff > 0 and cutoff < 1
cutoff_value = cutoff * matrix.sum()
mask = elements[:, 0] >= cutoff_value
elements = elements[mask, :]
row_lookup, col_lookup = {}, {}
data = []
for amount, row, col in elements:
if row not in row_lookup:
row_lookup[row] = obj_lookup(reverse_row[row])
if col not in col_lookup:
col_lookup[col] = obj_lookup(reverse_col[col])
row_obj, col_obj = row_lookup[row], col_lookup[col]
obj = {'amount': amount}
for field in fields:
obj[f"row_{field}"] = row_obj.get(field)
obj[f"col_{field}"] = col_obj.get(field)
data.append(obj)
return pd.DataFrame(data)
I hope this is self-explanatory. Here is an example of it in action:
import bw2data as bd
import bw2calc as bc
bd.projects.set_current("ecoinvent-3.8-cutoff")
ei = bd.Database("ecoinvent-3.8-cutoff")
fu = {ei.random(): 1}
ipcc = ('IPCC 2013', 'climate change', 'GWP 100a')
lca = bc.LCA(fu, ipcc)
lca.lci()
lca.lcia()
reverse_col, _, reverse_row = lca.reverse_dict()
to_dataframe(lca.inventory, reverse_row, reverse_col)