在Brightway的循环中将多个活动保存到数据库

时间:2016-07-14 20:46:01

标签: brightway

我有一个生成数据并将其写入数据库的循环:

myDatabase = Database('myDatabase')
for i in range(10):
    #some code here that generates dictionaries that can be saved as activities
     myDatabase.write({('myDatabase', 'valid code'): activityDict})

这样创建的单个活动可以保存到数据库中。但是,在创建多个数据库时,数据库的长度始终为1,只有最后一个活动进入数据库。

因为我有很多非常大的数据集,所以将它们全部存储在一个字典中并一次写入数据库是不方便的。

有没有办法逐步将活动添加到现有数据库?

1 个答案:

答案 0 :(得分:1)

正常活动写作

Database.write()将替换整个数据库。最好的方法是在python中创建数据库,然后编写整个文件:

data = {}
for i in range(10):
    # some code here that generates data
    data['foo'] = 'bar'
Database('myDatabase').write(data)

动态生成数据集

但是,如果要从现有数据库动态创建聚合数据集,则可以在自定义生成器中创建单个数据集。该生成器需要支持以下内容:

  • __iter__:返回数据库键。用于检查每个数据集是否属于正在写入的数据库。因此,我们只需要返回第一个元素。
  • __len__:要写入的数据集数量。
  • keys:用于向mapping添加密钥。
  • values:用于向geomapping添加活动地点。由于我们的源数据库和聚合系统数据库中的位置相同,我们可以在此处提供原始数据集。
  • items:新密钥和数据集。

以下是代码:

class IterativeSystemGenerator(object):
    def __init__(self, from_db_name, to_db_name):
        self.source = Database(from_db_name)
        self.new_name = to_db_name
        self.lca = LCA({self.source.random(): 1})
        self.lca.lci(factorize=True)

    def __len__(self):
        return len(self.source)

    def __iter__(self):
        yield ((self.new_name,))

    def get_exchanges(self):
        vector = self.lca.inventory.sum(axis=1)
        assert vector.shape == (len(self.lca.biosphere_dict), 1)
        return [{
                    'input': flow,
                    'amount': float(vector[index]),
                    'type': 'biosphere',
                } for flow, index in self.lca.biosphere_dict.items()
                if abs(float(vector[index])) > 1e-17]

    def keys(self):
        for act in self.source:
            yield (self.new_name, act['code'])

    def values(self):
        for act in self.source:
            yield act

    def items(self):
        for act in self.source:
            self.lca.redo_lci({act: 1})
            obj = copy.deepcopy(act._data)
            obj['database'] = self.new_name
            obj['exchanges'] = self.get_exchanges()
            yield ((self.new_name, obj['code']), obj)

用法:

new_name = "ecoinvent 3.2 cutoff aggregated"
new_data = IterativeSystemGenerator("ecoinvent 3.2 cutoff", new_name)
Database(new_name).write(new_data)            

此方法的局限性

如果您在数据集中编写了如此多的数据集或交换,而您遇到了内存问题,那么您也可能使用了错误的工具。当前的数据库表和矩阵构建器系统使用稀疏矩阵。在这种情况下,密集矩阵会更有意义。例如,IO table backend完全跳过数据库,只写processed arrays。如果生物圈矩阵有13.000 * 1.500 = 20.000.000个条目,则需要很长时间才能加载和创建生物圈矩阵。在这种特殊情况下,我的第一直觉是尝试下列之一:

  • 不要将生物圈流写入数据库,但要按照汇总流程单独保存,然后在库存计算后添加它们。
  • 为每个聚合系统进程创建一个单独的数据库。