-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ab5b69f
commit 58164da
Showing
5 changed files
with
227 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -165,4 +165,6 @@ cython_debug/ | |
.DS_Store | ||
|
||
# development environment | ||
bw_webapp_dev/ | ||
bw_webapp_dev/ | ||
|
||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
# %% | ||
import bw_graph_tools as bgt | ||
import bw2io as bi | ||
import bw2data as bd | ||
import bw2calc as bc | ||
import pandas as pd | ||
|
||
from bw2data.backends.proxies import Activity | ||
from bw_graph_tools.graph_traversal import Node | ||
|
||
if 'USEEIO-1.1' not in bd.projects: | ||
bi.install_project(project_key="USEEIO-1.1", overwrite_existing=True) | ||
bd.projects.set_current("USEEIO-1.1") | ||
else: | ||
bd.projects.set_current("USEEIO-1.1") | ||
|
||
useeio = bd.Database("USEEIO-1.1") | ||
|
||
cars_activity = bd.utils.get_node( | ||
database = 'USEEIO-1.1', | ||
name = 'Automobiles; at manufacturer', | ||
type = 'product', | ||
location = 'United States' | ||
) | ||
|
||
method_gcc = bd.Method(('Impact Potential', 'GCC')) | ||
lca = bc.LCA( | ||
demand={cars_activity: 1}, | ||
method = method_gcc.name # attention here: it's not the Method object, just its name!!! | ||
) | ||
lca.lci() | ||
lca.lcia() | ||
|
||
graph_traversal: dict = bgt.NewNodeEachVisitGraphTraversal.calculate(lca, cutoff=0.005) | ||
|
||
|
||
def nodes_dict_to_dataframe(nodes: dict) -> pd.DataFrame: | ||
""" | ||
Returns a dataframe with human-readable descriptions and emissions values of the nodes in the graph traversal. | ||
Parameters | ||
---------- | ||
nodes : dict | ||
A dictionary of nodes in the graph traversal. | ||
Can be created by selecting the 'nodes' key from the dictionary | ||
returned by the function `bw_graph_tools.NewNodeEachVisitGraphTraversal.calculate()`. | ||
Returns | ||
------- | ||
pd.DataFrame | ||
A dataframe with human-readable descriptions and emissions values of the nodes in the graph traversal. | ||
""" | ||
list_of_row_dicts = [] | ||
for i in range(0, len(nodes)-1): | ||
current_node: Node = nodes[i] | ||
scope_1: bool = False | ||
if current_node.unique_id == 0: | ||
scope_1 = True | ||
else: | ||
pass | ||
list_of_row_dicts.append( | ||
{ | ||
'UID': current_node.unique_id, | ||
'Scope 1?': scope_1, | ||
'Name': bd.get_node(id=current_node.activity_datapackage_id)['name'], | ||
'Cumulative': current_node.cumulative_score, | ||
'Direct': current_node.direct_emissions_score, | ||
'Depth': current_node.depth, | ||
'activity_datapackage_id': current_node.activity_datapackage_id, | ||
} | ||
) | ||
return pd.DataFrame(list_of_row_dicts) | ||
|
||
|
||
def edges_dict_to_dataframe(edges: dict) -> pd.DataFrame: | ||
""" | ||
To be added... | ||
""" | ||
if len(edges) < 2: | ||
return pd.DataFrame() | ||
else: | ||
list_of_row_dicts = [] | ||
for i in range(0, len(edges)): | ||
current_edge: Edge = edges[i] | ||
list_of_row_dicts.append( | ||
{ | ||
'consumer_unique_id': current_edge.consumer_unique_id, | ||
'producer_unique_id': current_edge.producer_unique_id | ||
} | ||
) | ||
return pd.DataFrame(list_of_row_dicts).drop(0) | ||
|
||
|
||
def trace_branch(df: pd.DataFrame, start_node: int) -> list: | ||
""" | ||
Given a dataframe of graph edges and a starting node, returns the branch of nodes that lead to the starting node. | ||
For example: | ||
| consumer_unique_id | producer_unique_id | | ||
|--------------------|--------------------| | ||
| 0 | 1 | # 1 is terminal producer node | ||
| 0 | 2 | | ||
| 0 | 3 | | ||
| 2 | 4 | # 4 is terminal producer node | ||
| 3 | 5 | | ||
| 5 | 6 | # 6 is terminal producer node | ||
For start_node = 6, the function returns [0, 3, 5, 6] | ||
Parameters | ||
---------- | ||
df : pd.DataFrame | ||
Dataframe of graph edges. Must contain integer-type columns 'consumer_unique_id' and 'producer_unique_id'. | ||
start_node : int | ||
The integer indicating the starting node to trace back from. | ||
Returns | ||
------- | ||
list | ||
A list of integers indicating the branch of nodes that lead to the starting node. | ||
""" | ||
|
||
branch: list = [start_node] | ||
|
||
while True: | ||
previous_node: int = df[df['producer_unique_id'] == start_node]['consumer_unique_id'] | ||
if previous_node.empty: | ||
break | ||
start_node: int = previous_node.values[0] | ||
branch.insert(0, start_node) | ||
|
||
return branch | ||
|
||
|
||
def add_branch_information_to_dataframe(df: pd.DataFrame) -> pd.DataFrame: | ||
""" | ||
Adds 'branch' information to terminal nodes in a dataframe of graph edges. | ||
For example: | ||
| consumer_unique_id | producer_unique_id | | ||
|--------------------|--------------------| | ||
| 0 | 1 | # 1 is terminal producer node | ||
| 0 | 2 | | ||
| 0 | 3 | | ||
| 2 | 4 | # 4 is terminal producer node | ||
| 3 | 5 | | ||
| 5 | 6 | # 6 is terminal producer node | ||
| consumer_unique_id | producer_unique_id | branch | | ||
|--------------------|--------------------|--------------| | ||
| 0 | 1 | [0, 1] | | ||
| 0 | 2 | [0, 2] | | ||
| 0 | 3 | [0, 3] | | ||
| 2 | 4 | [0, 2, 4] | | ||
| 3 | 5 | [0, 3, 5] | | ||
| 5 | 6 | [0, 3, 5, 6] | | ||
Parameters | ||
---------- | ||
df_edges : pd.DataFrame | ||
A dataframe of graph edges. | ||
Must contain integer-type columns 'consumer_unique_id' and 'producer_unique_id'. | ||
Returns | ||
------- | ||
pd.DataFrame | ||
A dataframe of graph nodes with a column 'branch' that contains the branch of nodes that lead to the terminal producer node. | ||
""" | ||
# initialize empty list to store branches | ||
branches: list = [] | ||
|
||
for _, row in df.iterrows(): | ||
branch: list = trace_branch(df, int(row['producer_unique_id'])) | ||
branches.append({ | ||
'producer_unique_id': int(row['producer_unique_id']), | ||
'Branch': branch | ||
}) | ||
|
||
return pd.DataFrame(branches) | ||
|
||
|
||
def merge_enriched_edge_dataframe_into_nodes_dataframe(df_left, df_right): | ||
""" | ||
Merges the enriched edges DataFrame with the nodes DataFrame | ||
to add branch information. | ||
Note that the last row is dropped, since | ||
| UID | ... | | ||
|-----|-----| | ||
| 0 | ... | | ||
| 1 | ... | | ||
| 2 | ... | | ||
""" | ||
self.df_graph_traversal_nodes = pd.merge( | ||
df_nodes, | ||
df_edges_enriched, | ||
left_on='UID', | ||
right_on='producer_unique_id', | ||
how='left' | ||
).iloc[:-1] # the |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.