Apache spark 中的数据框示例 |斯卡拉
Dataframe sample in Apache spark | Scala
我正在尝试从两个数据框中提取样本,其中我需要保持计数比率。例如
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吗?我检查了 and 但无法完全理解它。
另外,我们是否可以指定要采样的行数?
fraction
参数表示将 return 编辑的数据集的 近似值 部分。例如,如果将其设置为 0.1
,则 10% (1/10) 的行将被 returned。对于您的情况,我相信您想执行以下操作:
val newSample = df1.sample(true, 1D*noOfSamples/df1.count)
但是,您可能会注意到,每次 运行 时,newSample.count
都会 return 一个不同的数字,这是因为 fraction
将是一个阈值随机生成的值(如您所见 ),因此生成的数据集大小可能会有所不同。解决方法可以是:
val newSample = df1.sample(true, 2D*noOfSamples/df1.count).limit(df1.count/noOfSamples)
一些可扩展性观察结果
您可能会注意到,执行 df1.count
可能会很昂贵,因为它会评估整个 DataFrame,并且您会失去在第一个采样中获得的好处之一地方。
因此,根据您的应用程序的上下文,您可能希望使用已经已知 的样本总数,或近似值。
val newSample = df1.sample(true, 1D*noOfSamples/knownNoOfSamples)
或者假设您的 DataFrame 的大小很大,我仍然会使用 fraction
并使用 limit
来强制样本数量。
val guessedFraction = 0.1
val newSample = df1.sample(true, guessedFraction).limit(noOfSamples)
关于您的问题:
can it be greater than 1?
没有。它表示 0 到 1 之间的分数。如果将它设置为 1,它将带来 100% 的行,因此将它设置为大于 1 的数字没有意义。
Also is there anyway we can specify the number of rows to be sampled?
您可以指定比所需行数更大的分数,然后使用限制,如我在第二个示例中所示。也许还有另一种方法,但这是我使用的方法。
也许你想试试下面的代码..
val splits = data.randomSplit(Array(0.7, 0.3))
val (trainingData, testData) = (splits(0), splits(1))
回答小数是否可以大于1。是的,如果我们将其替换为是,则可以。如果用 replace false 提供了大于 1 的值,则会出现以下异常:
java.lang.IllegalArgumentException: requirement failed: Upper bound (2.0) must be <= 1.0.
我也发现缺少样本计数功能令人不安。如果您对创建临时视图不挑剔,我发现下面的代码很有用(df 是您的数据框,count 是样本大小):
val tableName = s"table_to_sample_${System.currentTimeMillis}"
df.createOrReplaceTempView(tableName)
val sampled = sqlContext.sql(s"select *, rand() as random from ${tableName} order by random limit ${count}")
sqlContext.dropTempTable(tableName)
sampled.drop("random")
它 returns 只要您当前的行数与您的样本量一样大,它就是一个精确的计数。
当需要确切的记录数时,我使用此函数进行随机抽样:
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)
为了回答您的问题,我们是否可以指定要采样的行数?
我最近需要从 spark 数据框中采样一定数量的行。我遵循了以下过程,
将spark数据帧转换为rdd。
示例:df_test.rdd
RDD 有一个名为 takeSample 的功能,它允许您使用种子编号提供所需的样本数量。
示例:df_test.rdd.takeSample(withReplacement, Number of Samples, Seed)
使用sqlContext.createDataFrame()
将RDD转换回spark数据帧
以上流程合为一步:
我需要从中采样的数据框(或人口)有大约 8,000 条记录:
df_grp_1
df_grp_1
test1 = sqlContext.createDataFrame(df_grp_1.rdd.takeSample(False,125,seed=115))
test1 数据框将有 125 个采样记录。
我正在尝试从两个数据框中提取样本,其中我需要保持计数比率。例如
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吗?我检查了
另外,我们是否可以指定要采样的行数?
fraction
参数表示将 return 编辑的数据集的 近似值 部分。例如,如果将其设置为 0.1
,则 10% (1/10) 的行将被 returned。对于您的情况,我相信您想执行以下操作:
val newSample = df1.sample(true, 1D*noOfSamples/df1.count)
但是,您可能会注意到,每次 运行 时,newSample.count
都会 return 一个不同的数字,这是因为 fraction
将是一个阈值随机生成的值(如您所见
val newSample = df1.sample(true, 2D*noOfSamples/df1.count).limit(df1.count/noOfSamples)
一些可扩展性观察结果
您可能会注意到,执行 df1.count
可能会很昂贵,因为它会评估整个 DataFrame,并且您会失去在第一个采样中获得的好处之一地方。
因此,根据您的应用程序的上下文,您可能希望使用已经已知 的样本总数,或近似值。
val newSample = df1.sample(true, 1D*noOfSamples/knownNoOfSamples)
或者假设您的 DataFrame 的大小很大,我仍然会使用 fraction
并使用 limit
来强制样本数量。
val guessedFraction = 0.1
val newSample = df1.sample(true, guessedFraction).limit(noOfSamples)
关于您的问题:
can it be greater than 1?
没有。它表示 0 到 1 之间的分数。如果将它设置为 1,它将带来 100% 的行,因此将它设置为大于 1 的数字没有意义。
Also is there anyway we can specify the number of rows to be sampled?
您可以指定比所需行数更大的分数,然后使用限制,如我在第二个示例中所示。也许还有另一种方法,但这是我使用的方法。
也许你想试试下面的代码..
val splits = data.randomSplit(Array(0.7, 0.3))
val (trainingData, testData) = (splits(0), splits(1))
回答小数是否可以大于1。是的,如果我们将其替换为是,则可以。如果用 replace false 提供了大于 1 的值,则会出现以下异常:
java.lang.IllegalArgumentException: requirement failed: Upper bound (2.0) must be <= 1.0.
我也发现缺少样本计数功能令人不安。如果您对创建临时视图不挑剔,我发现下面的代码很有用(df 是您的数据框,count 是样本大小):
val tableName = s"table_to_sample_${System.currentTimeMillis}"
df.createOrReplaceTempView(tableName)
val sampled = sqlContext.sql(s"select *, rand() as random from ${tableName} order by random limit ${count}")
sqlContext.dropTempTable(tableName)
sampled.drop("random")
它 returns 只要您当前的行数与您的样本量一样大,它就是一个精确的计数。
当需要确切的记录数时,我使用此函数进行随机抽样:
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)
为了回答您的问题,我们是否可以指定要采样的行数?
我最近需要从 spark 数据框中采样一定数量的行。我遵循了以下过程,
将spark数据帧转换为rdd。 示例:
df_test.rdd
RDD 有一个名为 takeSample 的功能,它允许您使用种子编号提供所需的样本数量。 示例:
df_test.rdd.takeSample(withReplacement, Number of Samples, Seed)
使用
sqlContext.createDataFrame()
将RDD转换回spark数据帧
以上流程合为一步:
我需要从中采样的数据框(或人口)有大约 8,000 条记录: df_grp_1
df_grp_1
test1 = sqlContext.createDataFrame(df_grp_1.rdd.takeSample(False,125,seed=115))
test1 数据框将有 125 个采样记录。