DataFrame基本结构化操作

DataFrame是Row类型的Dataset集合。

spark.range(2).toDF().collect()

spark类型:可以通过如下使用Scala类型

import org.apache.spark.sql._
val b = ByteType

DataFrame创建示例

val df = spark.read.format("json")
.loan("/data/t.json")

DF的转换操作

可以通过获取一组行并将它们转换操作为一个DF来即时创建DF

import org.apache.spark.sql.Row
import org.apache.spark.sql.types.{StructField, StructType, StringType, LongType}
val myManualSchema = new StructType(Array(
new StructField("some", StringType, true),
new StructField("col", StringType, true),
new StructField("names", Longype, false)))
val myRows = Seq(Row("Hello", null ,1L))
val myRDD = spark.sparkContext.parallelize(myRows)
val myDf = spark.createDataFrame(myRDD, myManualSchema)
myDf.show()

创建的df可以通过如下方式查看模式:

df.printSchema()
df.schema

有很多方法来构建,如:

import org.apache.spark.sql.functions.{col,column}
col("someColumnName")
column("someColumnName")
$"myColumn"
'myColumn
//如果想显示的引用某一列
df.col("count")

列的表达式:

expr("someCol") 等同于 col("someCol")
(((col("someCol") + 5) * 200) - 6 ) < col("otherCol") 等同于
expr("(((someCol + 5) * 200 ) - 6 ) < otherCol")

可以使用columns属性查询DF的所有列:

df.columns

更改列类型

df.withColumn("count2",col("count").cast("long"))

添加列

withColum函数,此函数有两个参数,分别为列名和赋值表达式

//添加一个仅包含1的列
df.withColum("numberOne", lit(1)).show(2)
DEST_COUNTRY_NAMEcountnumberOne
United States151
United States21
//当出发国家与目的国家相同时,设置为一个bool标志
df.withColumn("withinCounter",expr("ORIGIN_COUNTRY_NAME == DEST_COUNTRY_NAME"))
	.show(2)

也可以使用这个函数给字段重命名

df.withColumn("newName",expr("DEST_COUNTRY_NAME")).columns

重命名列函数:withColumnRenamed(原列名, 新列名)

df.withColumnRenamed("DEST_COUNTRY_NAME","DEST").columns

删除列

df.drop("DEST_COUNTRY_NAME").columns

可以通过以下方式查看df的一行

df.first()

可以通过手动创建Row对象来创建DF的列,但是需要保证与DF的列顺序一致

import org.apache.spark.sql.Row
val myRow = Row("hello",null, 1, false)
//访问行的数据
myRow(0) //任意类型
myRow(0).asInstanceOf[String] //字符串
myRow.getString(0) //字符串
myRow.getInt(2) //整型

过滤行使用filter或where,两者作用相同

//一般使用where操作
df.filter(col("count") < 2).show(2)
df.where("count < 2 ").show(2)
df.where(col("count") < 2).where(col("DEST_COUNTRY_NAME") =!= "Croatia")

获取去重后的行

//对select中的两列进行去重
df.select("ROIGIN_COUNTRY_NAME", "DEST_COUNTRY_NAME").distinct().count()

连接和追加行

使用union操作

import org.apache.spark.sql.Row
val schema = df.schema
val newRows = Seq(
	Row("New Country", "Other Country" , 5L),
	Row("New Country 2", "Other Country 3" , 1L)
)
val parallelizedRows = spark.sparkContext.parallelize(newRows)
val newDF = spark.createDataFrame(parallelizedRows, schema)
df.union(newDF)
	.where("count = 1")
	.where($"ROIGIN_COUNTRY_NAME" =!= "United States")
	.show()

tip: =!= 不仅能比较字符串,还能比较表达式

行排序

sort和orderBy方法是等效的:

df.sort("count").show()
df.orderBy("count", "DEST_COUNTRY_NAME").show(2)
//指定升序还是降序
import org.apache.spark.sql.functions{desc, asc}
df.orderBy(expr("count desc ")).show(2)
df.orderBy(desc("count"), asc("DEST_COUNTRY_NAME")).show(2)

重划分和合并

根据一些经常过滤的列队数据进行分区,控制跨集群数据的物理布局,重新分区会导致数据的全面洗牌。
如果经常根据某一列执行过滤操作,那么根据该列进行重新分区是很有必要的。

df.repartition(col("DEST_COUNTRY_NAME"))
//也可以指定分区的数量
df.repartition(5, col("dest_country_name"))

select函数和selectExpr函数

//select查看列的方式
df.select(df.col("a"),
			col("b"),
			column("c"),
			'd,
			$"e",
			expr("f")).show()
			
df.select("a","b").show()

//使用expr重命名,将ods_name重命名为new_name后,在重命名回去
df.select(expr("old_name as new_name").alias("old_name"))

df.selectExpr("ols_name as  new_name", "aa").show(2)

我们可以使用selectExpr构建复杂表达式来创建DF

//在原有列的基础上加一列boolean的判断列withinCountry
df.selectExpr("*", // 包含所有原始表中的列
				"DEST_SOUNTRY_NAME = ORIGIN_SOUNTRY_NAME as withinCountry")
				.show(2)

可以使用系统定义好的聚合函数

df.selectExpr("avg(count)", "count(distinct(DEST_COUNTRY_NAME))").show(2)

转换操作spark类型(字面量)

有时候需要显示的传递给spark一个值,可能是一个常量或者是接下来需要比较的值,这种情况需要用到literal(字面量)

df.select(expr("*"), lit(1).as("one")).show(2)

结果如下:

DEST_COUNTRY_NAMEcountone
United States151
United States21

随机抽样与随机分割

随机抽样使用sample方法,通过withReplacement参数指定是否放回

df.sample(withReplacement = false, 0.5 , seed = 5).count()

随机分割可以按照比例分成几份:

val fataFrames : Array[DataFrame] = df.randomSplit(Array(0.25,0.75), seed)
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页