Apache spark Apache spark | Scala中的数据帧示例

Apache spark Apache spark | Scala中的数据帧示例,apache-spark,dataframe,sample,Apache Spark,Dataframe,Sample,我试图从两个数据帧中提取样本,其中我需要保持计数比率。乙二醇 df1.count() = 10 df2.count() = 1000 noOfSamples = 10 我希望以这样的方式对数据进行采样,即我得到10个大小为101的样本(1个来自df1,100个来自df2) 现在这样做的时候, var newSample = df1.sample(true, df1.count() / noOfSamples) println(newSample.count()) 这里的分数意味着什么?它能

我试图从两个数据帧中提取样本,其中我需要保持计数比率。乙二醇

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

noOfSamples = 10
我希望以这样的方式对数据进行采样,即我得到10个大小为101的样本(1个来自df1,100个来自df2)

现在这样做的时候,

var newSample = df1.sample(true, df1.count() / noOfSamples)
println(newSample.count())
这里的分数意味着什么?它能大于1吗?我检查了一下,但不能完全理解


还有,我们是否可以指定要采样的行数?

参数表示将返回的数据集的aproximate分数。例如,如果将其设置为
0.1
,将返回10%(1/10)行。对于您的情况,我相信您希望做到以下几点:

val newSample = df1.sample(true, 1D*noOfSamples/df1.count)
但是,您可能会注意到,
newSample.count
每次运行时都会返回不同的数字,这是因为
分数将是随机生成值的阈值(如您所见),因此生成的数据集大小可能会有所不同。解决方法可以是:

val newSample = df1.sample(true, 2D*noOfSamples/df1.count).limit(df1.count/noOfSamples)
一些可伸缩性观察结果

您可能会注意到,执行
df1.count
可能会很昂贵,因为它会评估整个数据帧,并且您首先会失去采样的一个好处

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

val newSample = df1.sample(true, 1D*noOfSamples/knownNoOfSamples)
或者假设数据帧的大小非常大,我仍然会使用
分数
,并使用
限制
来强制增加样本数

val guessedFraction = 0.1
val newSample = df1.sample(true, guessedFraction).limit(noOfSamples)
至于您的问题:

它能大于1吗

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

另外,我们是否可以指定要采样的行数


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

参数
表示将返回的数据集的aproximate部分。例如,如果将其设置为
0.1
,将返回10%(1/10)行。对于您的情况,我相信您希望做到以下几点:

val newSample = df1.sample(true, 1D*noOfSamples/df1.count)
但是,您可能会注意到,
newSample.count
每次运行时都会返回不同的数字,这是因为
分数将是随机生成值的阈值(如您所见),因此生成的数据集大小可能会有所不同。解决方法可以是:

val newSample = df1.sample(true, 2D*noOfSamples/df1.count).limit(df1.count/noOfSamples)
一些可伸缩性观察结果

您可能会注意到,执行
df1.count
可能会很昂贵,因为它会评估整个数据帧,并且您首先会失去采样的一个好处

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

val newSample = df1.sample(true, 1D*noOfSamples/knownNoOfSamples)
或者假设数据帧的大小非常大,我仍然会使用
分数
,并使用
限制
来强制增加样本数

val guessedFraction = 0.1
val newSample = df1.sample(true, guessedFraction).limit(noOfSamples)
至于您的问题:

它能大于1吗

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

另外,我们是否可以指定要采样的行数


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

可能是您想要尝试下面的代码

val splits = data.randomSplit(Array(0.7, 0.3))
val (trainingData, testData) = (splits(0), splits(1))

可能你想试试下面的代码

val splits = data.randomSplit(Array(0.7, 0.3))
val (trainingData, testData) = (splits(0), splits(1))

回答分数是否可以大于1。是的,如果我们将替换为是,则可以。如果为大于1的值提供了replace false,则将发生以下异常:

java.lang.IllegalArgumentException: requirement failed: Upper bound (2.0) must be <= 1.0.

java.lang.IllegalArgumentException:需求失败:如果分数可以大于1,则上限(2.0)必须为。是的,如果我们将替换为是,则可以。如果为大于1的值提供了replace false,则将发生以下异常:

java.lang.IllegalArgumentException: requirement failed: Upper bound (2.0) must be <= 1.0.

java.lang.IllegalArgumentException:需求失败:上限(2.0)必须是我也发现缺少按计数采样功能令人不安。如果您对创建临时视图不挑剔,我发现下面的代码很有用(df是您的数据帧,count是样本大小):


只要当前行计数与样本大小一样大,它就会返回一个精确的计数

我也发现缺乏计数抽样功能令人不安。如果您对创建临时视图不挑剔,我发现下面的代码很有用(df是您的数据帧,count是样本大小):


只要当前行计数与样本大小一样大,它就会返回一个精确的计数

当需要准确数量的记录时,我使用此函数进行随机抽样:

def row_count_sample (df, row_count, with_replacement=False, random_seed=113170):

    ratio = 1.08 * float(row_count) / df.count()  # random-sample more as dataframe.sample() is not a guaranteed to give exact record count
                                                  # it could be more or less actual number of records returned by df.sample()

    if ratio>1.0:
        ratio = 1.0

    result_df = (df
                    .sample(with_replacement, ratio, random_seed)
                    .limit(row_count)                                   # since we oversampled, make exact row count here
                )

    return result_df 

当需要准确数量的记录时,我使用此函数进行随机抽样:

def row_count_sample (df, row_count, with_replacement=False, random_seed=113170):

    ratio = 1.08 * float(row_count) / df.count()  # random-sample more as dataframe.sample() is not a guaranteed to give exact record count
                                                  # it could be more or less actual number of records returned by df.sample()

    if ratio>1.0:
        ratio = 1.0

    result_df = (df
                    .sample(with_replacement, ratio, random_seed)
                    .limit(row_count)                                   # since we oversampled, make exact row count here
                )

    return result_df 

如果要对数据帧df进行70%和30%的随机拆分,下面的代码可以工作

val Array(trainingDF, testDF) = df.randomSplit(Array(0.7, 0.3), seed = 12345)

如果要对数据帧df进行70%和30%的随机拆分,下面的代码可以工作

val Array(trainingDF, testDF) = df.randomSplit(Array(0.7, 0.3), seed = 12345)

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

我最近需要从spark数据帧中采样一定数量的行。我遵循了以下流程

  • 将spark数据帧转换为rdd。 示例:
    df_test.rdd

  • RDD有一个名为takeSample的功能,允许您使用种子编号提供所需的样本数。 示例:
    df_test.rdd.takeSample(带替换、样本数量、种子)

  • 使用
    sqlContext.createDataFrame()

  • 在上面