Apache spark中的数据帧示例 斯卡拉

hba*_*bar 21 sample dataframe apache-spark

我试图从两个数据帧中取出样本,其中我需要保持计数的比率.例如

df1.count() = 10
df2.count() = 1000

noOfSamples = 10
Run Code Online (Sandbox Code Playgroud)

我想以这样一种方式对数据进行采样,即每个样本大小为101个样本(1个来自df1,100个来自df2)

现在这样做,

var newSample = df1.sample(true, df1.count() / noOfSamples)
println(newSample.count())
Run Code Online (Sandbox Code Playgroud)

这里的分数意味着什么?它可以大于1吗?我检查这个这个,但没能完全理解它.

无论如何我们还可以指定要采样的行数吗?

Dan*_*ula 33

fraction参数表示将返回的数据集的近似部分.例如,如果将其设置为0.1,则将返回10%(1/10)的行.对于您的情况,我相信您想要做以下事情:

val newSample = df1.sample(true, 1D*noOfSamples/df1.count)
Run Code Online (Sandbox Code Playgroud)

但是,您可能会注意到newSample.count每次运行时都会返回不同的数字,这是因为fraction它将是随机生成的值的阈值(如此处所示),因此生成的数据集大小可能会有所不同.解决方法可以是:

val newSample = df1.sample(true, 2D*noOfSamples/df1.count).limit(df1.count/noOfSamples)
Run Code Online (Sandbox Code Playgroud)

一些可扩展性观察

您可能会注意到,在df1.count评估整个DataFrame时执行可能会很昂贵,并且您将首先失去采样的一个好处.

因此,根据应用程序的上下文,您可能希望使用已知数量的总样本或近似值.

val newSample = df1.sample(true, 1D*noOfSamples/knownNoOfSamples)
Run Code Online (Sandbox Code Playgroud)

或者假设您的DataFrame的大小很大,我仍然会使用a fraction并使用limit强制样本数量.

val guessedFraction = 0.1
val newSample = df1.sample(true, guessedFraction).limit(noOfSamples)
Run Code Online (Sandbox Code Playgroud)

至于你的问题:

它可以大于1吗?

它表示0到1之间的分数.如果将其设置为1,它将带来100%的行,因此将其设置为大于1的数字是没有意义的.

无论如何我们还可以指定要采样的行数吗?

您可以指定比您想要的行数更大的分数,然后使用limit,如我在第二个示例中所示.也许有另一种方式,但这是我使用的方法.


小智 5

为了回答您的问题,我们是否可以指定要采样的行数?

我最近需要从 Spark 数据框中采样一定数量的行。我遵循以下过程,

  1. 将 Spark 数据帧转换为 rdd。例子:df_test.rdd

  2. RDD 有一个名为 takeSample 的功能,它允许您使用种子号给出所需的样本数量。例子:df_test.rdd.takeSample(withReplacement, Number of Samples, Seed)

  3. 使用以下命令将 RDD 转换回 Spark 数据帧sqlContext.createDataFrame()

上述过程合并为单个步骤:

我需要采样的数据框(或总体)有大约 8,000 条记录:df_grp_1

df_grp_1
test1 = sqlContext.createDataFrame(df_grp_1.rdd.takeSample(False,125,seed=115))
Run Code Online (Sandbox Code Playgroud)

test1 数据框将有 125 个采样记录。