由于scala中 对DataFrame 方式为 sample() 方法
sample : 采样
采样变换根据给定的随机种子,从RDD中随机地按指定比例选一部分记录,创建新的RDD。采样变换 在机器学习中可用于进行交叉验证。
语法
def sample(withReplacement: Boolean, fraction: Double, seed: Long = Utils.random.nextLong): RDD[T]参数
withReplacement : Boolean , True表示进行替换采样,False表示进行非替换采样
fraction : Double, 在0~1之间的一个浮点值,表示要采样的记录在全体记录中的比例
seed :随机种子
var sample_frac = (extract_nums/result_data.count().toFloat).formatted("%.2f").toFloat
result_data_sample = result_data.sample(false, sample_frac)
这样就有问题 :
1.当sample_frac采样率✖️数据总条数 出现小数时 采样数据总条数未必等于例子中的extract_nums(采样条数)
2.当采样率过小 或者 采样率*数据总条数<1 时 采样数据为空
所以今天介绍一种全新的采样方式,可以采样出等于extract_nums(采样条数) 的数据
take:无序采样
使用take成员函数获得指定数量的记录,返回一个数组。与top不同,take在提取记录 前不进行排序,它仅仅逐分区地提取够指定数量的记录就返回结果。可以将take方法 视为对RDD对象的无序采样。
语法
def take(num: Int): Array[T]
参数 num : Int , 要获取的记录数量
返回值
包含指定数量记录的数组,记录类型为T。
代码如下:
import spark.implicits._
var data3 = Seq(
(null, "2002", "196", "1", "bai"),
(null, "4004", "192", "2", "wang"),
(null, "9009", "126", "1", "bai"),
(null, "9009", "126", "5", "wei"),
("1","10010", "19219", "5", "wei")
).toDF("label", "AMOUNT", "Pclass", "nums", "name")
import org.apache.spark.sql.functions._
data3 = data3.withColumn("AMOUNT", col("AMOUNT").cast("int"))
data3.show()
+-----+------+------+----+----+
|label|AMOUNT|Pclass|nums|name|
+-----+------+------+----+----+
| null| 2002| 196| 1| bai|
| null| 4004| 192| 2|wang|
| null| 9009| 126| 1| bai|
| null| 9009| 126| 5| wei|
| 1| 10010| 19219| 5| wei|
+-----+------+------+----+----+
//查看data3各列数据类型
data3.dtypes.toMap
res835: scala.collection.immutable.Map[String,String] = Map(name -> StringType, label -> StringType, Pclass -> StringType, AMOUNT -> IntegerType, nums -> StringType)
//使用take抽取3条 并转化为Seq 只有Seq才能构建DataFrame
var rdd = sc.parallelize(data3.take(3).toSeq)
//重新构建 DataFrame表结构 与原表对应 名称可以不同 但是对应类型必须相同 这就是前面看原表类型的原因
val schema = new StructType().add(StructField("label", StringType, true)).add(StructField("AMOUNT", IntegerType, true)).add(StructField("Pclass", StringType, true)).add(StructField("nums",StringType, true)).add(StructField("name", StringType, true))
val df = spark.createDataFrame(rdd, schema)
df.show()
+-----+------+------+----+----+
|label|AMOUNT|Pclass|nums|name|
+-----+------+------+----+----+
| null| 2002| 196| 1| bai|
| null| 4004| 192| 2|wang|
| null| 9009| 126| 1| bai|
+-----+------+------+----+----+
注:如果某列全为null 空 类型设置为 NullType
涉及到Row构造DataFrame知识参考:
https://www.itranslater.com/qa/details/2325684091590542336