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

Python 什么';从文件中创建输入变量N个排列的PCollection最惯用的方法是什么?,python,google-cloud-dataflow,apache-beam,Python,Google Cloud Dataflow,Apache Beam,我正在尝试使用ApacheBeam来并行化模拟的N试验。该模拟在一个矩阵V上运行,该矩阵来源于.matMATLAB文件。我的第一反应(请原谅,我对Apache Beam/Dataflow不熟悉)是扩展FileBasedSource,但进一步的调查使我确信情况并非如此。最明确的是,表示“如果您想使用源API提供的高级功能,就应该创建一个新的源代码”,我不需要它们中的任何一个—我只想读取一个(或几个)变量!我最终偶然发现了这一点,这就是我现在想要获得V(将生成的类文件对象从FileSystems.o

我正在尝试使用ApacheBeam来并行化模拟的
N
试验。该模拟在一个矩阵
V
上运行,该矩阵来源于
.mat
MATLAB文件。我的第一反应(请原谅,我对Apache Beam/Dataflow不熟悉)是扩展
FileBasedSource
,但进一步的调查使我确信情况并非如此。最明确的是,表示“如果您想使用源API提供的高级功能,就应该创建一个新的源代码”,我不需要它们中的任何一个—我只想读取一个(或几个)变量!我最终偶然发现了这一点,这就是我现在想要获得
V
(将生成的类文件对象从
FileSystems.open
传递到
scipy.io.loadmat

下一个问题是如何创建
N的
PCollection
V的置换。显而易见的解决方案是类似于beam.Create([permutation(V)for uu.in xrange(N)])
。然而,我对“后者主要用于测试和调试目的”中的评论有点反感。也许稍微改进一下是在
DoFn
中执行排列

我还有最后一个想法。这听起来有点愚蠢(很可能很愚蠢),但请听我讲完这一点(幽默我睡眠不足的自我)。指向
CountingSource
(以及与其一起的
ReadFromCountingSource
)的实现。使用
ReadFromCountingSource(N)
优于
beam.Create(range(N))
?如果是这样,以下(开始)管道是否合理:

(p | 'trial_count' >> ReadFromCountingSource(N)
   | 'permute_v' >> beam.FlatMap(lambda _, x: permutation(x), V)
   | ...)
Beam/数据流专家,您有什么建议


谢谢

让我重新表述一下你的问题,如果我错了,请纠正我:

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

编辑:
FileBasedSource
不能直接使用。我已经更正了下面的解释。

ApacheBeam具有内置的PTransforms,可用于读取多种文件格式,但不能读取MATLAB文件。您需要创建自己的源代码实现并读取转换。有许多基于
FileBasedSource
的示例,例如和

Beam文档提供了实现新I/O转换的技巧:

如果将置换逻辑与源代码解耦,则添加置换逻辑将更简单。如果在管道构造过程中试用次数
N
是静态的或已知的,则可以使用和普通Python代码返回每个排列的iterable。所以你的逻辑看起来更像:

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

要将矩阵从
.mat
文件加载到
PCollection
中,请从
梁中导出
PTransform
包装器
scipy.io.loadmat
。创建

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))
                | ...)

对不起,我想你误解了。我的结论是,
FileBasedSource
不是我问题的正确答案。首先,你不能只做
FileBasedSource(文件名)
,对吗?您需要对
FileBasedSource
进行子类化,因为
read\u records
(可能还有其他内容)不是为
FileBasedSource
定义的。此外,
FileBasedSource
似乎适用于从文件中获取
PCollection
文本行/JSON对象/某些内容的情况,特别是如果该读取可以并行化,而在我的情况下(尤其是
.mat
是二进制格式)。关于排列:我面临的基本挑战是Apache Beam/Dataflow模型似乎非常适合于获取
m
对象的
PCollection
,并将其转换为
m
对象的另一个
PCollection
,或者按键分组并减少输出
PCollection
对象的数量,而不是我想做的:取
PCollection
M
(在我的例子中,1)个对象,并将其转换为
PCollection
M*N
对象。假设
permutation
调用返回一个
N
对象列表,比如我在原始问题中的实现
[permutation(V)for uu in N]
。@user1093967感谢您指出我的原始答案在使用
FileBasedSource
时不正确。我已经更新了我的答案,以反映您需要子类化并创建读取转换。对于排列,
FlatMap
可以为单个输入输出多个元素。正如我在问题和对您答案的初步评论中所写,我认为使用源API创建新的源代码不是这里的答案。在问我的问题之前,我已经研究了
AvroSource
的代码和其他示例,并在过去几天里重新访问了它们。我仍然不明白它在这种情况下是如何应用的。我将用我昨天最终得出的解决方案添加一个答案,并且欢迎您看看这在我的用例中是否更合理。