通过例子学习spark dataframe--基础函数和Action函数

spark dataframe–基础函数和Action函数

基础函数

  • 说明
    基础函数主要包括对dataframe的行列元数据的获取和操作函数,数据集的转换函数等。

测试的数据集如下:

$ hadoop fs -cat /user/zxh/csvdata/csvdata
id,name,subject,score
1,n1,s1,10
2,n2,s2,20
3,n3,s3,30
3,n3,s1,20
4,n4,s2,40
5,n5,s3,50
6,n6,s1,60
7,n6,s2,40
8,n8,s3,90
8,n9,s1,30
9,n9,s1,20
9,n9,s2,70

通过以下函数获取数据dataframe

import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder().appName("Spark SQL basic example").config("spark.some.config.option", "some-value").getOrCreate()
import spark.implicits._
val df = spark.read.format("csv").option("header", true).load("/user/zxh/csvdata/csvdata")
df.show()

columns

  • 功能说明
    返回所有列的列名,并按字符串数组返回。

  • 函数原型

def columns: Array[String] 
  • 使用例子
scala> df.columns
res1: Array[String] = Array(id, name, subject, score)

dtypes

  • 功能说明
    按元组的方式返回列名和该列的类型。

  • 函数原型

def dtypes: Array[(String, String)] 
  • 使用例子
scala> df.dtypes
res3: Array[(String, String)] = Array((id,StringType), (name,StringType), (subject,StringType), (score,StringType))

inputFiles

  • 功能
    返回该df对应的数据源,也就是对应的hdfs文件。
    注意:返回的可能是多个文件,所以返回的是一个字符串数组。

  • 函数原型

def inputFiles: Array[String]
  • 例子1
scala> df2.inputFiles
res5: Array[String] = Array(hdfs://hadoop.td.com/user/zxh/csvdata/csvdata)

printSchema

  • 功能
    打印出dataframe的表结构。
    注意:该函数返回的是Unit,只是打印而不是返回。

  • 原型

def printSchema(): Unit
  • 例子1
scala> df.printSchema
root
 |-- id: string (nullable = true)
 |-- name: string (nullable = true)
 |-- subject: string (nullable = true)
 |-- score: string (nullable = true)

rdd

  • 功能
    把dataframe转换成rdd。
    注意:该函数返回的是一个MapPartitionsRDD

  • 原型

lazy val rdd: RDD[T]
  • 例子1
scala> df.rdd
res8: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[13] at rdd at <console>:32

schema

  • 函数功能
    按StructType的格式打印出该df的表结构。

  • 函数原型

def schema: StructType
  • 例子1
scala> df.schema
res9: org.apache.spark.sql.types.StructType = StructType(StructField(id,StringType,true), StructField(name,StringType,true), StructField(subject,StringType,true), StructField(score,StringType,true))

scala> df.schema.foreach(println)
StructField(id,StringType,true)
StructField(name,StringType,true)
StructField(subject,StringType,true)
StructField(score,StringType,true)

write

  • 函数功能
    把dataframe进行持久化。
    注意:该函数可以指定持久化的格式,指定持久化驱动比如:jdbc,设置各种选项。

  • 函数原型

def write: DataFrameWriter[T]

注意:该函数返回的是一个DataFrameWriter类,该类提供了持久化的各种选项和参数设置。
该类的函数详细描述,请查看:这里

  • 例子1:按csv格式把dataframe写入hdfs目录
scala> import org.apache.spark.sql._
import org.apache.spark.sql._
scala> df.write.format("csv").option("header", true).mode(SaveMode.Overwrite).save("/user/zxh/writedata/")

保存的文件如下:

$ hadoop fs -cat /user/zxh/writedata/*
id,name,subject,score
1,n1,s1,10
2,n2,s2,20
3,n3,s3,30
3,n3,s1,20
4,n4,s2,40
5,n5,s3,50
6,n6,s1,60
7,n6,s2,40
8,n8,s3,90
8,n9,s1,30
9,n9,s1,20
9,n9,s2,70

注意:mode中的参数有以下几个:

SaveMode.Overwrite: overwrite the existing data.
SaveMode.Append: append the data.
SaveMode.Ignore: ignore the operation (i.e. no-op).
SaveMode.ErrorIfExists: default option, throw an exception at runtime.
  • 例子2 : 按csv格式写入,保留列名头,并指定分隔符
df.write
  .format("csv")
  .option("header", "true")
  .option("delimiter",<your delimiter>)
  .save(output)
  • 例子3: 按parquet格式写入
例如按以下分区和模式写入s3或hdfs目录。

df.write.partitionBy("Date", "category").mode(SaveMode.Append).parquet("s3://bucket/save/path")
或
df.write.partitionBy("eventDate", "category").mode(SaveMode.Overwrite).parquet("/user/zxh/writedata/");

// 实战例子
df.write.partitionBy("subject").mode(SaveMode.Overwrite).parquet("/user/zxh/writedata/");

$ hadoop fs -lsr /user/zxh/writedata/
lsr: DEPRECATED: Please use 'ls -R' instead.
-rw-r--r--   3 hadoop supergroup          0 2017-12-06 11:39 /user/zxh/writedata/_SUCCESS
drwxr-xr-x   - hadoop supergroup          0 2017-12-06 11:39 /user/zxh/writedata/subject=s1
-rw-r--r--   3 hadoop supergroup        763 2017-12-06 11:39 /user/zxh/writedata/subject=s1/part-00000-f87ae8ca-3cf8-48c1-a911-cdb10b66f09f.snappy.parquet
drwxr-xr-x   - hadoop supergroup          0 2017-12-06 11:39 /user/zxh/writedata/subject=s2
-rw-r--r--   3 hadoop supergroup        732 2017-12-06 11:39 /user/zxh/writedata/subject=s2/part-00000-f87ae8ca-3cf8-48c1-a911-cdb10b66f09f.snappy.parquet
drwxr-xr-x   - hadoop supergroup          0 2017-12-06 11:39 /user/zxh/writedata/subject=s3
-rw-r--r--   3 hadoop supergroup        701 2017-12-06 11:39 /user/zxh/writedata/subject=s3/part-00000-f87ae8ca-3cf8-48c1-a911-cdb10b66f09f.snappy.parquet
  • 例子4
    把dataframe写入到一个表中。
df.write().mode(SaveMode.Ignore).format("csv").saveAsTable("myTableName")

Action函数

说明:action函数会触发计算并返回结果。Action函数是分布式函数,在单机版的spark中可能打印不出内容。
而且action函数很多情况下是返回Unit,因为在很多时候这些函数是数据处理的最后一步。

本节使用的数据如下:

$ hadoop fs -cat /user/zxh/csvdata/csvdata
id,name,subject,score
1,n1,s1,10
2,n2,s2,20
3,n3,s3,30
3,n3,s1,20
4,n4,s2,40
5,n5,s3,50
6,n6,s1,60
7,n6,s2,40
8,n8,s3,90
8,n9,s1,30
9,n9,s1,20
9,n9,s2,70

count

  • 功能
    返回dataframe的列数。

  • 函数原型

def count(): Long 
  • 例子
scala> df.count()
res12: Long = 12
  • 函数实现
  def count(): Long = withCallback("count", groupBy().count()) { 
    df => df.collect(needCallback = false).head.getLong(0)
  }

可见:count()是通过collect()函数来实现的。

foreachPartition

  • 函数功能
    遍历dataframe的分区,并执行遍历的函数。

  • 函数原型

def foreachPartition(f: (Iterator[T]) => Unit): Unit
  • 例子1
df.foreachPartition(r=>println(r))

注意:单机版的spark能够看到输出,否则可能看不到输出。

head 和 first

  • 函数功能
    从df取一行。

  • 函数原型和实现

 def first(): T = head()
 def head(): T = head(1).head

 // head(n)的实现
  def head(n: Int): Array[T] = withTypedCallback("head", limit(n)) { df =>
    df.collect(needCallback = false)
  }

注意:这两个函数都会把数据加载到driver端的内存中。若数据量太大,可能会出现driver端的内存溢出。

takeAsList

  • 函数功能
    返回dataframe的前n行,其内容按list的方式返回。

  • 函数原型

def takeAsList(n: Int): List[T]
  • 例子1
scala> df.takeAsList(3)
res2: java.util.List[org.apache.spark.sql.Row] = [[1,n1,s1,10], [2,n2,s2,20], [3,n3,s3,30]]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值