Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 实现luigi动态图形配置_Python_Python 3.x_Luigi_Data Pipeline - Fatal编程技术网

Python 实现luigi动态图形配置

Python 实现luigi动态图形配置,python,python-3.x,luigi,data-pipeline,Python,Python 3.x,Luigi,Data Pipeline,我是luigi的新手,在为我们的ML工作设计管道时遇到了它。虽然它不适合我的特定用例,但它有很多额外的特性,我决定让它适合我 基本上,我所寻找的是一种能够持久化定制管道的方法,从而使其结果可重复并易于部署,在阅读了大多数在线教程后,我尝试使用现有的luigi.cfg配置和命令行机制实现序列化,它可能已经满足任务参数的要求,但无法序列化管道的DAG连接,因此,我决定创建一个WrapperTask,它接收一个json配置文件,然后创建所有任务实例并连接luigi任务的所有输入输出通道(执行所有管道)

我是luigi的新手,在为我们的ML工作设计管道时遇到了它。虽然它不适合我的特定用例,但它有很多额外的特性,我决定让它适合我

基本上,我所寻找的是一种能够持久化定制管道的方法,从而使其结果可重复并易于部署,在阅读了大多数在线教程后,我尝试使用现有的
luigi.cfg
配置和命令行机制实现序列化,它可能已经满足任务参数的要求,但无法序列化管道的DAG连接,因此,我决定创建一个WrapperTask,它接收一个
json配置文件
,然后创建所有任务实例并连接luigi任务的所有输入输出通道(执行所有管道)

我谨随函附上一份小型测试计划供您审阅:

import random
import luigi
import time
import os


class TaskNode(luigi.Task):
    i = luigi.IntParameter()  # node ID

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.required = []

    def set_required(self, required=None):
        self.required = required  # set the dependencies
        return self

    def requires(self):
        return self.required

    def output(self):
        return luigi.LocalTarget('{0}{1}.txt'.format(self.__class__.__name__, self.i))

    def run(self):
        with self.output().open('w') as outfile:
            outfile.write('inside {0}{1}\n'.format(self.__class__.__name__, self.i))
        self.process()

    def process(self):
        raise NotImplementedError(self.__class__.__name__ + " must implement this method")


class FastNode(TaskNode):

    def process(self):
        time.sleep(1)


class SlowNode(TaskNode):

    def process(self):
        time.sleep(2)


# This WrapperTask builds all the nodes 
class All(luigi.WrapperTask):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        num_nodes = 513

        classes = TaskNode.__subclasses__()
        self.nodes = []
        for i in reversed(range(num_nodes)):
            cls = random.choice(classes)

            dependencies = random.sample(self.nodes, (num_nodes - i) // 35)

            obj = cls(i=i)
            if dependencies:
                obj.set_required(required=dependencies)
            else:
                obj.set_required(required=None)

            # delete existing output causing a build all
            if obj.output().exists():
                obj.output().remove()  

            self.nodes.append(obj)

    def requires(self):
        return self.nodes


if __name__ == '__main__':
    luigi.run()
因此,基本上,正如问题标题中所述,这关注于动态依赖关系,并生成
p=1/35连通概率的
513节点依赖DAG
,它还将All(如make All中所述)类定义为一个WrapperTask,需要构建所有节点才能将其视为完成(我有一个版本,它只连接到连接的DAG组件的头部,但我不想过于复杂)

是否有更高的标准(Luigic)实现方法?特别注意TaskNodeinit和set_required方法的复杂性,我之所以这样做,是因为init方法中接收参数的方式与luigi注册参数的方式有冲突。我还尝试了其他几种方法,但这基本上是最合适的方法(成功了)

如果没有一个标准的方法,我仍然希望在我完成框架的实现之前,听到您对我计划的方法有什么见解。

我昨天做了一个演示。我几乎完全是基于。在文档中,通过
yeild
ing任务分配动态依赖项似乎是他们喜欢的方式


<代码>路易吉.CONFIG和动态依赖关系可能会给你一个几乎无限的灵活性的管道。他们还描述了一个虚拟的<代码>任务<代码>,它调用多个依赖链,可以给你更多的控制。

相关的未回答的问题,你有没有考虑过路易吉的气流?我用它来做或多或少的E。正如你在问题中所说的:我看了一小段,但它似乎更多地围绕着cmdline而不是python,这只是一个懒惰的第一印象吗?我不必这么说。它带有一个web ui,围绕着DAG的计划或触发执行。如果你喜欢,你可以从命令行手动运行DAG。虽然这是一个非常大的包,但它有一些依赖项,对于您的情况来说可能有些过头了。例如,它至少需要一个sqlite db。嗯,听起来很有趣,而且有传言说它比现在的luigi维护得更好,我可能会在下一轮(或我的下一份工作)研究它,但我现在对luigi已经有点力不从心了:/