从文件中创建输入变量的N个排列的PCollection的最常用方法是什么?

时间:2018-02-02 09:02:32

标签: python google-cloud-dataflow apache-beam

我尝试使用Apache Beam来并行化模拟的N次试验。此模拟在源自V MATLAB文件的矩阵.mat上运行。我的第一直觉(原谅我,我是Apache Beam / Dataflow的新手)是延长FileBasedSource,但进一步的调查使我确信情况并非如此。最明确的是,Apache Beam documentation表示,"如果您想使用Source API提供的高级功能,则应创建新的来源,"我不需要其中任何一个 - 我只想读一个变量(或几个)!我最终偶然发现了https://stackoverflow.com/a/45946643,这就是我现在打算获得V(将结果类似文件的对象从FileSystems.open传递给scipy.io.loadmat)。

下一个问题是如何创建PCollection N Vbeam.Create([permutation(V) for _ in xrange(N)])的排列。显而易见的解决方案就像DoFn。但是,我对the documentation中的评论略有抛弃,"后者主要用于测试和调试目的。"也许稍微改进就是在CountingSource中执行排列。

我有一个最后的想法。这听起来有点愚蠢(而且很可能是愚蠢的),但是请听我这个(幽默我的睡眠剥夺的自我)。 The documentation指向ReadFromCountingSource的实施(以及ReadFromCountingSource(N))。使用beam.Create(range(N))优于Pipeline是否有好处?如果是,则以下(开始)(p | 'trial_count' >> ReadFromCountingSource(N) | 'permute_v' >> beam.FlatMap(lambda _, x: permutation(x), V) | ...) 合理:

dot -Tpng input.dot > output.png

Beam / Dataflow专家,您会推荐什么?

谢谢!

2 个答案:

答案 0 :(得分:0)

要将.mat文件中的矩阵加载到PCollection,请从PTransform scipy.io.loadmat beam.Create周围导出class LoadMat(beam.Create): def __init__(self, file_name, mdict=None, appendmat=True, **kwargs): mat_dict = scipy.io.loadmat(file_name, mdict, appendmat, **kwargs) super(LoadMat, self).__init__([mat_dict]) 包装器:

with beam.Pipeline(options=pipeline_options) as p:
    matrices = (p
                | 'LoadMat' >> LoadMat(FileSystems.open(known_args.input))
                | ...)

按如下方式调用此转换:

.gitignore

答案 1 :(得分:-1)

让我重新说一下我的想法,如果我错了,请纠正我:

MATLAB文件中有一个矩阵V,需要读入,然后通过模拟的N试验运行。

编辑:FileBasedSource无法直接使用。我在下面更正了我的解释。

Apache Beam内置了PTransforms,可以读取多种文件格式,但不能读取MATLAB文件。您需要创建自己的源实现和读取转换。有许多基于FileBasedSource的示例,例如ReadFromTFRecordReadFromAvro

Beam文档提供了有关实现新I / O转换的提示:https://beam.apache.org/documentation/io/authoring-overview/

如果排列逻辑与源分离,则添加排列逻辑会更简单。如果试验次数N在管道构建期间是静态的或已知的,则可以使用FlatMap和普通的Python代码返回每个排列的迭代。所以你的逻辑看起来更像是:

(p | 'read' >> ReadFromMatlab(file_name)
   | 'permute_v' >> beam.FlatMap(lambda x: permutation(x, N))
   | ...)