我尝试使用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
V
个beam.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专家,您会推荐什么?
谢谢!
答案 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
的示例,例如ReadFromTFRecord
和ReadFromAvro
。
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))
| ...)