Spark DataFrame列拆分与合并

1. 列拆分

hdfs目录下/home/test/testSplitTxt.txt文件内容

a,b,c,d
123,345,789,5
34,45,90,9878

读取text文件

scala> val df = sqlContext.read.text("/home/test/testSplitTxt.txt")
df: org.apache.spark.sql.DataFrame = [value: string]

scala> df.show
+-------------+
|        value|
+-------------+
|      a,b,c,d|
|123,345,789,5|
|34,45,90,9878|
+-------------+

1.1 方法一:生成字段结构再与数据关联

生成字段属性

import org.apache.spark.ml.attribute.{Attribute, NumericAttribute}
val fields = Array("a","b","c","d")
val attributes: Array[Attribute] = {
    Array.tabulate(fields.length)(i => NumericAttribute.defaultAttr.withName(fields(i)))
}

将属性与字段关联

import org.apache.spark.sql.functions._
val fieldCols = attributes.zipWithIndex.map(x => {
    val assembleFunc = udf {
	str: String =>
    	str.split(",")(x._2)
    }
    assembleFunc(df("value")).as(x._1.name.get, x._1.toMetadata())
})

显示数据

scala> df.select(col("*") +: fieldCols: _*).show
+-------------+---+---+---+----+
|        value|  a|  b|  c|   d|
+-------------+---+---+---+----+
|      a,b,c,d|  a|  b|  c|   d|
|123,345,789,5|123|345|789|   5|
|34,45,90,9878| 34| 45| 90|9878|
+-------------+---+---+---+----+

scala> df.select(fieldCols: _*).show
+---+---+---+----+
|  a|  b|  c|   d|
+---+---+---+----+
|  a|  b|  c|   d|
|123|345|789|   5|
| 34| 45| 90|9878|
+---+---+---+----+

1.2 方法二:拆分为数组后遍历

按指定分隔符拆分为数组列

scala> val splitDF = df.withColumn("splitCols",split(col("value"), ","))
splitDF: org.apache.spark.sql.DataFrame = [value: string, splitCols: array<string>]

scala> splitDF.show
+-------------+------------------+
|        value|         splitCols|
+-------------+------------------+
|      a,b,c,d|      [a, b, c, d]|
|123,345,789,5|[123, 345, 789, 5]|
|34,45,90,9878|[34, 45, 90, 9878]|
+-------------+------------------+

遍历数组生成各列

scala> splitDF.select(col("splitCols").getItem(0).as("a"),col("splitCols").getItem(1).as("b"),col("splitCols").getItem(2).as("c"),col("splitCols").getItem(3).as("d")).show 
+---+---+---+----+
|  a|  b|  c|   d|
+---+---+---+----+
|  a|  b|  c|   d|
|123|345|789|   5|
| 34| 45| 90|9878|
+---+---+---+----+

或者按指定分隔符拆分value列,生成splitCols列

var newDF = df.withColumn("splitCols", split(col("value"), ","))
    attributes.zipWithIndex.foreach(x => {
      newDF = newDF.withColumn(x._1, $"splitCols".getItem(x._2))
})

2. 列合并

DataFrame中的数据为

scala> df.show
+---+---+---+----+
|  a|  b|  c|   d|
+---+---+---+----+
|  a|  b|  c|   d|
|123|345|789|   5|
| 34| 45| 90|9878|
+---+---+---+----+

2.1 方法一: 使用concat_ws函数

获取df各列的Column对象

scala> val columnArr = df.columns.map { colName => df.col(colName)}
columnArr: Array[org.apache.spark.sql.Column] = Array(a, b, c, d)

将各列使用指定分隔符拼接并获取

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._

scala> df.select(concat_ws(",", columnArr: _*).cast(StringType).as("value")).show
+-------------+
|        value|
+-------------+
|      a,b,c,d|
|123,345,789,5|
|34,45,90,9878|
+-------------+

2.2 方法二:使用map函数

使用map函数遍历各列拼接(会将dataFrame转化为rdd)

scala> val rdd = df.map(_.toSeq.foldLeft("")(_ + "," + _).substring(1)) 
rdd: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[24] at map at <console>:36

scala> rdd.take(3)
res17: Array[String] = Array(a,b,c,d, 123,345,789,5, 34,45,90,9878)
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当你在ZeppelinSpark集成后,你可以使用Zeppelin来编写和运行Spark代码。下面是一个简单的Zeppelin Spark实例,演示了如何使用Spark进行数据处理: 1. 打开Zeppelin,并创建一个新的笔记。 2. 在笔记页面,选择要使用的解释器为Spark。 3. 在第一个代码块,我们将使用Spark读取一个文本文件,并计算单词的数量: ```scala %spark val textFile = sc.textFile("/path/to/textfile.txt") val wordCount = textFile.flatMap(line => line.split(" ")) .map(word => (word, 1)) .reduceByKey(_ + _) wordCount.collect().foreach(println) ``` 这段代码使用`sc.textFile()`方法读取一个文本文件,然后使用`flatMap()`和`map()`方法对每一行进行单词拆分和计数,最后使用`reduceByKey()`方法将相同单词的计数进行合并。最后,我们使用`collect()`方法将结果打印出来。 4. 在第二个代码块,我们将使用Spark SQL查询一个数据表,并显示结果: ```scala %spark val df = spark.read.format("csv").option("header", "true").load("/path/to/data.csv") df.createOrReplaceTempView("data") val result = spark.sql("SELECT * FROM data WHERE age > 30") result.show() ``` 这段代码使用`spark.read.format().load()`方法读取一个CSV文件,并将其加载到DataFrame。然后,我们使用`createOrReplaceTempView()`方法将DataFrame注册为一个临时表,以便使用Spark SQL进行查询。最后,我们使用`spark.sql()`方法执行查询,并使用`show()`方法显示结果。 这只是一个简单的Zeppelin Spark实例,你可以根据自己的需求进行更复杂的数据处理和分析。希望这个例子能帮助你开始使用Zeppelin和Spark!如有任何问题,请随时向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值