我想使用数据流对静态数据源进行采样。我知道有一个Sample
转换允许您采样固定数量的数据元组,但在我的用例中有不同之处在于我的目标样本数是基于实际源大小的动态。
我知道有一种方法是我可以先计算我的数据源,计算我的采样概率并使用ParDo过滤我的pcollection,每个DoFn内部都会翻转硬币。
然而,一个缺点是它似乎不是很稳定,特别是当我的概率非常低时(例如,如果我想从500M +池中随机挑选50个样本)。
所以我只是想知道,有没有更好的办法呢? (不知何故,我觉得这只是一些我不知道的数据流黑客)
编辑:
抱歉这令人困惑。问题是我事先不知道源的大小,它们的范围可能从1M到500M,并且根据我的实际大小,我想以不同的方式对其进行采样,比如我的样本大小为min(actual_size,2.5e10 /( actual_size)),这使得当我的源大小恰好是500M时,我只想要50个。当我的实际尺寸是5M时,我想抽样5000。特别是,我想知道:
是否有可用于此特定用例的内置PTranform
(假设我可以使用Sample
,但只是使用了一些解决方法吗?)
答案 0 :(得分:1)
我不认为有一个内置的转换来处理这个问题。问题是随着你的集合变大,你描述的函数实际上想要生成一个较小的样本。
似乎有几种方法可以尝试解决这个问题:
编写一个使用CombineFn
作为累加器的自定义List
,并构建采样元素的列表。这种方法的问题在于,在最坏的情况下,你需要有一个158113元素的列表,它需要适合内存 - 这可能是不可取的。
使用Count
转换来计算出有多少元素,并将其用作执行过滤的DoFn
的侧输入。 DoFn
可以读取侧输入以找出总输入大小,然后根据该输入大小执行概率采样。