Spark之Row

前言

一直在说Dataframe是Dataset的特例,DataFrame=Dataset[Row],可Row是什么东西呢?

什么是Row

顾名思义:就是一行数据
Row是org.apache.spark.sql包下的一个特质
简单的理解:
Row是一个类型,跟Car、Person这些的类型一样,所有的表结构信息都用Row来表示

什么时候会用到这个Row呢?

煮个例子

通过读取文件创建一个DataFrame:

    import spark.implicits._
    val dfA: DataFrame = spark.read.textFile(path = "./data/infoA")
      .map(_.split(","))
      .map(x => (x(0), x(1)))
      .toDF("tel", "name")

如果要把这个DataFrame转换为Dataset,只需要写个样例类,然后调用DataFrame的as方法:

case class User(tel: String, name: String)
import spark.implicits._
val dsA: Dataset[User] = spark.read.textFile(path = "./data/infoA")
      .map(_.split(","))
      .map(x => (x(0), x(1)))
      .toDF("tel", "name")
      .as[User]

这个列子想说明,如果返回的是DataFrame,那么其实可以看成是Dataset[Row]。

那么如何处理这个Row类型的Dataset呢?

先从官网举的几个"无用"的例子说起

  • 在Java中可以使用 RowFactory.create() 来创建Row,在Scala中用 Row.apply() 创建
  • Row可以通过几个字段来构建
    import org.apache.spark.sql._
    // Create a Row from values.
    val row1 = Row(1, true, "a string", null)
    // Create a Row from a Seq of values.
    val row2 = Row.fromSeq(Seq(1, true, "a string", null))
  • 如何访问Row的数据
import org.apache.spark.sql._

val row = Row(1, true, "a string", null)
// row: Row = [1,true,a string,null]
val firstValue = row(0)
// firstValue: Any = 1
val fourthValue = row(3)
// fourthValue: Any = null

// using the row from the previous example.
val firstValue = row.getInt(0)
// firstValue: Int = 1
val isNull = row.isNullAt(3)
// isNull: Boolean = true
  • 在Scala中还可以进行模式匹配:
import org.apache.spark.sql._

val pairs = sql("SELECT key, value FROM src").rdd.map {
  case Row(key: Int, value: String) =>
    key -> value
}

上面的案例在开发中几乎没有用,写上纯属是为了进一步感受Row是个什么东西

Row在开发中可能用到的场景

说实话,基本上对于研发人员来说,真正使用Row的场景不多,因为现在使用spark进行开发一般都是:

spark.sql("SELECT * FROM TABLE A")

这样的句式返回的正是DataFrame或者说是Dataset[Row]
可如果想要处理这个Row,就有点难办了,比如我要把整个手机号存入到一个Array或者List中,一般都要把Row转为String,这个时候就用到了Row的mkString()方法

    val dfA: DataFrame = spark.read.textFile(path = "./data/infoA")
      .map(_.split(","))
      .map(x => (x(0), x(1)))
      .toDF("tel", "name")
    val telArr: Array[String] = dfA.select("tel").map(row => row.mkString).collect()
    val telList: List[String] = telArr.toList
    val telSeq: Seq[String] = telArr.toSeq
    println(telList)
    println(telSeq)

结果:

List(13111111111, 13222222222, 13333333333, 13444444444, 13555555555, 13666666666, 13777777777, 13888888888, 13999999999)

WrappedArray(13111111111, 13222222222, 13333333333, 13444444444, 13555555555, 13666666666, 13777777777, 13888888888, 13999999999)
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SunnyRivers

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值