You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Brightway 2.5用datapackage结合Ecoinvent对比场景遇矩阵错误求助

Brightway 2.5中使用datapackage修改场景交换项时遇到非方阵错误的解决求助

我需要编写代码,在同一个包含活动和交换项的数据库下对比不同场景,每次运行时更新交换项数值。为了避免逐个用exc['amount']和exc.save()更新交换项,我知道用datapackage可以实现更高效的操作,参考相关内容编写了示例代码,但运行时出现错误:

bw2calc.errors.NonsquareTechnosphere: Technosphere matrix is not square: 1 activities (columns) and 4 products (rows).

最终我要处理50余个场景,以及包含约70个新活动的数据库,怀疑错误源于Ecoinvent与自建数据库的关联问题,求结合Ecoinvent数据库的datapackage代码示例。

环境信息

  • Python 3.12.2
  • Brightway 2.5相关包版本:
bw2calc                   2.0.dev18                  
bw2data                   4.0.dev46                
bw2io                     0.9.dev30                                     
bw_processing             0.9.6     

示例代码

import bw2data as bd
import bw2io as bi
import numpy as np
import bw2calc as bc
import bw_processing as bwp


bd.projects.set_current("Save3")

# ====== 导入Ecoinvent ======
if 'Ecoinvent_3.9.1_apos' in bd.databases:
    print("数据库已导入。")

# ====== 创建数据库 ====== 
MyDB = bd.Database('MyDB')
MyDB.register()

eidb = bd.Database('Ecoinvent_3.9.1_apos')
eidb.order_by='name'
bio = bd.Database("biosphere3")

# ====== 创建新活动 ====== 
Prod_Sirop = MyDB.new_activity(code='Psirop', name="糖浆生产", unit="千克",
                            comment="基准年(2019年)的糖浆生产")
Prod_Sirop.save()

electricityMix_FR = bd.utils.get_node(database = 'Ecoinvent_3.9.1_apos', name = 'market for electricity, medium voltage', location = 'FR', unit = 'kilowatt hour')
Prod_Sirop.new_exchange(input=electricityMix_FR.key, amount=0,unit="kWh", type="technosphere").save()

market_selsNACl = bd.utils.get_node(database = 'Ecoinvent_3.9.1_apos', name = 'market for sodium chloride, powder', location = 'GLO', unit = 'kilogram')
Prod_Sirop.new_exchange(input=market_selsNACl.key, amount=50000, unit="千克", type="technosphere").save()

SiropProduction = 20000000 # 立方米/年
Prod_Sirop.new_exchange(input=Prod_Sirop, amount=SiropProduction, unit="立方米", type="production").save()
Prod_Sirop.save()


# ====== 创建datapackage ====== 
dp_newscenario = bwp.create_datapackage()

t_indices= np.array([(electricityMix_FR.id, Prod_Sirop.id),
                     (market_selsNACl.id, Prod_Sirop.id)],
                    dtype=bwp.INDICES_DTYPE)
t_data =np.array([2000, 4000])

# 创建新场景向量
dp_newscenario.add_persistent_vector(
    matrix='technosphere_matrix',
    indices_array=t_indices,
    data_array=t_data,
    flip_array=np.array([True, True]),
    name='Sc1')

# ====== 执行LCI/LCIA ====== 
lca = bc.LCA(
    demand={Prod_Sirop: 1},
    data_objs=[dp_newscenario],
    use_distributions=False,
    use_arrays=True,
    method=('ReCiPe 2016 v1.03, midpoint (H)','climate change','global warming potential (GWP1000)'))

lca.lci()
lca.lcia()

问题原因与修正方案

错误原因

出现非方阵错误的核心问题是:初始化LCA对象时仅传入了自定义场景的datapackage,未包含Ecoinvent、biosphere3及自建数据库的基础数据。Brightway无法获取Ecoinvent活动对应的矩阵维度信息,导致技术矩阵行/列数量不匹配。

修正后的代码示例

import bw2data as bd
import numpy as np
import bw2calc as bc
import bw_processing as bwp

bd.projects.set_current("Save3")

# 加载所有必要数据库
eidb = bd.Database('Ecoinvent_3.9.1_apos')
mydb = bd.Database('MyDB')
bio = bd.Database("biosphere3")

# 获取目标活动与Ecoinvent节点
Prod_Sirop = mydb.get(code='Psirop')
electricityMix_FR = bd.utils.get_node(database='Ecoinvent_3.9.1_apos', name='market for electricity, medium voltage', location='FR', unit='kilowatt hour')
market_selsNACl = bd.utils.get_node(database='Ecoinvent_3.9.1_apos', name='market for sodium chloride, powder', location='GLO', unit='kilogram')

# ====== 创建场景datapackage(仅包含需要修改的交换项) ====== 
dp_scenario1 = bwp.create_datapackage()

# 技术矩阵索引格式:(供应方ID, 需求方ID)
# flip_array=True表示该交换项为消耗(对应技术矩阵中的负向值)
t_indices = np.array([
    (electricityMix_FR.id, Prod_Sirop.id),
    (market_selsNACl.id, Prod_Sirop.id)
], dtype=bwp.INDICES_DTYPE)
t_data = np.array([2000, 4000])  # 场景1的新交换项数值

dp_scenario1.add_persistent_vector(
    matrix='technosphere_matrix',
    indices_array=t_indices,
    data_array=t_data,
    flip_array=np.array([True, True]),
    name='Scenario_1'
)

# ====== 初始化LCA,传入所有基础数据与场景修改 ====== 
# 顺序要求:基础数据库在前,场景datapackage在后(确保修改覆盖基础值)
lca = bc.LCA(
    demand={Prod_Sirop: 1},
    data_objs=[eidb, mydb, bio, dp_scenario1],
    use_distributions=False,
    use_arrays=True,
    method=('ReCiPe 2016 v1.03, midpoint (H)','climate change','global warming potential (GWP1000)')
)

lca.lci()
lca.lcia()
print(f"场景1的LCIA结果:{lca.score}")

# ====== 快速切换场景示例 ====== 
# 创建场景2的datapackage
dp_scenario2 = bwp.create_datapackage()
t_data2 = np.array([3000, 5000])
dp_scenario2.add_persistent_vector(
    matrix='technosphere_matrix',
    indices_array=t_indices,
    data_array=t_data2,
    flip_array=np.array([True, True]),
    name='Scenario_2'
)

# 重置LCA并加载新场景
lca.rebuild_lcia_data(data_objs=[eidb, mydb, bio, dp_scenario2])
lca.lci()
lca.lcia()
print(f"场景2的LCIA结果:{lca.score}")

关键注意事项

  • 数据对象顺序:基础数据库(Ecoinvent、自建库、biosphere)必须放在场景datapackage之前,确保场景修改能覆盖基础数据。
  • 索引与翻转数组:indices_array需严格对应(供应方ID, 需求方ID),flip_array的布尔值要匹配交换项类型(技术输入一般设为True)。
  • 批量场景处理:可将多个场景的datapackage存入列表,循环执行LCA计算,无需重复加载基础数据,提升效率。

内容的提问来源于stack exchange,提问作者mbess

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 13:10:11