向Spark的DataFrame增加一列数据

前言

先说个题外话,如何给hive表增加一个列,并且该把该列的所有字段设为’China’?
如果仅仅是增加一列倒是很简单:

alter table test add columns(flag string)

可要把这个flag字段全部设置为China,看起来的确是有点难度,因为往Hive表中装载数据的唯一途径就是使用一种“大量”的数据装载操作(如何往Hive表加载数据请参考),这个时候,如果数据集中本来就没有flag对应的数据,难道非要手动把China添加上去?这种情况,可以通过静态分区就能够解决:

load data local inpath '/data/test.txt' overwrite into table test partition (flag = 'China')

有人说,这不扯淡吗?如果这个China字段,并不是我们经常需要访问的字段,何须作为分区字段呢?的确是这样的,这个时候还可以通过下面的方式来解决这个问题:

insert into table test1  select id, name,'China' as flag from test;

好了步入正题:如何向Spark的DataFrame增加一列数据

案例详解

准备数据集:

张三,23
李四,24
王五,25
赵六,26

程序入口SparkSession和加载数据代码这里不再描述:

val spark = SparkSession
      .builder()
      .appName(this.getClass.getSimpleName)
      .master(master = "local[*]")
      .getOrCreate()

    import spark.implicits._
    val df = spark.read.textFile("./data/clm")
      .map(_.split(","))
      .map(x => (x(0), x(1)))
      .toDF("name", "age")
      .cache()
  • withColumn
    这个API是数据DataSet的,官网是这么定义的:

通过添加列或替换具有相同名称的现有列来返回新的数据集
column的表达式只能引用此数据集提供的属性。 添加引用其他数据集的列是错误的

新的列只能通过现有列转换得到,这个就有点局限,不过也能解决一部分问题:
比如,我想再增加一列为所有age增加1作为新的一列:

df.withColumn("new_age", col = df("age") + 1).show()

结果:

+----+---+-------+
|name|age|new_age|
+----+---+-------+
|张三| 23|   24.0|
|李四| 24|   25.0|
|王五| 25|   26.0|
|赵六| 26|   27.0|
+----+---+-------+

那么如果我想像前言中做那样的操作怎么办?

  • 使用sql增加默认列
df.createTempView(viewName = "view1")
import spark.sql
sql(sqlText = "select name,age,'一班' as class from view1").show()

结果:

+----+---+-----+
|name|age|class|
+----+---+-----+
|张三| 23| 一班|
|李四| 24| 一班|
|王五| 25| 一班|
|赵六| 26| 一班|
+----+---+-----+
  • 增加自增长列(类似于sql中的自增长主键)
    这里用到了functions.scala文件中的内置函数monotonically_increasing_id()

该函数官网的描述是:一个列表达式,用于生成单调递增的64位整数

import org.apache.spark.sql.functions._
df.withColumn("id", monotonically_increasing_id()).show()

结果:

+----+---+---+
|name|age| id|
+----+---+---+
|张三| 23|  0|
|李四| 24|  1|
|王五| 25|  2|
|赵六| 26|  3|
+----+---+---+

我们发现它是从0开始单调递增的,如果想从1开始递增:

import org.apache.spark.sql.functions._
df.withColumn("id", monotonically_increasing_id() + 1).show()

结果:

+----+---+---+
|name|age| id|
+----+---+---+
|张三| 23|  1|
|李四| 24|  2|
|王五| 25|  3|
|赵六| 26|  4|
+----+---+---+

你可能感兴趣的:(Spark)