Python 什么';从文件中创建输入变量N个排列的PCollection最惯用的方法是什么?
我正在尝试使用ApacheBeam来并行化模拟的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
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
的代码和其他示例,并在过去几天里重新访问了它们。我仍然不明白它在这种情况下是如何应用的。我将用我昨天最终得出的解决方案添加一个答案,并且欢迎您看看这在我的用例中是否更合理。