spark dataframe API 整理

本文介绍了如何从RDD转换为DataFrame,通过`df=rdd.map(lambda r:person(*r)).toDF()`创建DataFrame,并使用类型说明的方式进行数据类型定义。此外,还提及了使用`sqlContext.applySchema(rdd,schema)`创建DataFrame的方法,该方法会严格检查数据类型,如果数据不匹配则会报错,而且在rdd为空时仍能成功创建DataFrame。" 116753581,6676322,使用PyQT显示ROS图像数据,"['ROS开发', 'Python编程', 'GUI界面', '图像处理', 'PyQT']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1,从列表中创建dataframe
   列表的每一个元素转换成Row对象,利用parallelize()函数将列表转换成RDD,toDF()函数将RDD转换成dataframe
   from pyspark.sql import Row
   l=[Row(name='jack',age=10),Row(name='lucy',age=12)]
   df=sc.parallelize(l).toDF()
   
   从RDD中创建Dataframe:rdd中的数据没有schema,利用Row创建Schema,spark再根据抽样数据确定数据类型,如果定义不了,系统会给None(有点坑)
   l=[('jack',10),('lucy',12)]
   rdd=sc.parallelize(l)
   person=Row('name','age')

   df=rdd.map(lambda r:person(*r)).toDF()


   从RDD中创建Dataframe使用类型说明

   from pyspark.sql .types import *

  schema=StructType([StructField('name',StringType(),False)

    ,StructField('age',IntegerType(),False)]

  df=sqlContext.applySchema(rdd,schema)

  这一种方式会严格检查数据类型,如果数据不符合定义格式就报错;当rdd为空的时候,仍然能够成功创建dataframe


   
2,注册临时表
    df.registerTempTable("t1") 即可,但是t1表的只在当前sqlContext下有效
    df_table=sqlContext.tables() 命令可以查询所有表报表,临时表,HIVE表
    => table_name=sqlContext.tables()
    => t1=table_name.filter(table_name.isTemporary)
3,聚合函数的使用
   可以结合agg(),pyspark.sql.function来处理
   from pyspark.sql import functions as F
   => l=[Row(name='jack',age=10),Row(name='lucy',age=12)]
   => df=sc.parallelize(l).toDF()
   => max_age=df.agg(F.max(df.age)).first()[0]
4,groupby 分组聚合
   l=[Row(strategy='zhld',code='01',amount=100),Row(strategy='zhld',code='02',amount=200),Row(strategy='dxzl',code='03',amount=1000)]
   df=sc.parallelize(l).toDF()
   code_count=df.groupBy(df.strategy).agg(F.count(df.code).alias('num'))
   =>[Row(strategy='zhld',num=2),Row(strategy='dxzl',num=1)]
   
5,数据固化到内存的几种方式
如果数据需要经常用到,想基础表,但又不大这样的,可以持续更新到内存
cache  dataframe:df.cache()
6,dataframe 分区的合并
   dataframe始终是要转换成RDD进行计算的,dataframe的分区即为RDD的分区
   df.coalesce(1)  df的分区数合并到1
   df.rdd.getNumPartitions() 返回df的分区数
7,列的删除,有些情况需要关联表,这回引入新的列,可以使用drop,去掉新引入的列
   df=df.drop(df.name)
8, 去重  dropDumplicates()
l=[Row(strategy='zhld',code='01',amount=100),Row(strategy='zhld',code='02',amount=200),Row(strategy='dxzl',code='03',amount=1000)]
   df=sc.parallelize(l).toDF()
   df2=df.dropDumplicates(df.strategy)
9,fileter  None 值过滤,filter()接受True|False
df=df.filter(df.name.isNull())
df=df.filter(df.name.isNotNull())
10,求并集 intersec,求差集subtract
   l=[Row(strategy='zhld',code='01',amount=100),Row(strategy='zhld',code='02',amount=200),Row(strategy='dxzl',code='03',amount=1000)]
   df=sc.parallelize(l).toDF()
   df1=df.filter(df.strategy=='zhld')
   df2=df.intersect(df1)
   df3=df.subtract(df1)
11,replace 替换
    a=sc.parallelize([('alice',20,'beijing'),('john',30,'shanghai')])
    age=Row('name1','age','addr')
    a=a.map(lambda r:age(*r)).toDF()
    c=a.replace('alice','stefan',name1)
    c=a.replace(['alice','john'],['stefan','jace'],name)
12,show()查看dataframe 数据情况
13,select 中可以使用数据类型提供的函数
    整形的 between():a=ch.select(ch.name,ch.age.between(3,5).alias('flag')).show()    返回True|False
    字符串的 endswith():b=a.select(a.name,a.name.endswith('n'))
    字符串的 substr:a=ch.select(ch.age,ch.name.substr(2,3).alias('name1'))  从第二个字符开始,供三个字符
    F.when a=ch.select(ch.name,F.when(ch.age>3,1).when(ch.age<=3,-1).otherwise(0).alias('flag'))
    F提供的正则表达式:a=temp.select(F.regexp_extract(temp.str,'(\d+)-(\d+)',1).alias('d')
<think>好的,我现在需要帮助用户理解Spark中的RDD、DataFrame和DataSet的区别与用法。首先,我得回顾一下自己对这些概念的理解,确保没有错误。根据用户提供的引用资料,我需要整理出它们的主要特点和不同之处。 首先,RDD是Spark最早的数据结构,弹性分布式数据集,提供低层次的API,处理非结构化数据时比较灵活,但可能效率不高。用户给的引用提到RDD不支持Spark SQL操作,而且Spark不了解其内部结构,比如RDD[Person]中的Person类结构对Spark来说是透明的,这样优化可能受限。 接下来是DataFrame,它是在Spark 1.3引入的,以列的形式组织数据,类似于关系型数据库的表,有schema信息。这样Spark SQL可以利用结构信息进行优化,比如过滤、聚合等操作会更高效。引用1和3提到DataFrame是分布式的Row对象,有明确的列名和类型,支持SQL查询,适合结构化数据处理。但DataFrame的缺点可能是类型安全不够,因为Row是泛型,编译时无法检查类型错误。 然后是DataSet,Spark 1.6引入,结合了RDD和DataFrame的优点,提供强类型支持,同时利用优化器进行性能优化。引用1指出DataSet每个记录存储的是强类型值,而不是Row,这样可以在编译时捕捉错误,适合需要类型安全的场景。引用4提到版本演进,从RDD到DataFrame再到DataSet,说明DataSet是更高级的抽象。 接下来需要比较三者的区别和适用场景。比如,RDD适合需要细粒度控制的场景,比如非结构化数据或复杂的数据处理逻辑;DataFrame适合结构化数据,需要SQL操作或优化执行计划的情况;DataSet则结合两者,适合需要类型安全和高效计算的场景,特别是使用Scala的情况。 用户可能还想知道如何选择这三者,或者它们之间的性能差异。比如,DataFrame和DataSet因为有Catalyst优化器和Tungsten执行引擎,通常比RDD更快。此外,类型安全也是一个考虑因素,DataSet在Scala中可以提供编译时检查,而Python可能不支持DataSet。 需要确保回答结构清晰,分点说明每个概念的特点、区别、使用场景,并引用提供的资料来支持观点。同时,生成相关问题时要围绕这三个数据结构的应用和比较,比如优化方法、性能对比等。 最后,检查是否符合用户的要求,比如使用中文,LaTeX格式正确,添加引用标识,生成相关问题等。确保没有遗漏任何引用内容,并且正确对应引用编号。</think>### Spark中RDD、DataFrame和DataSet的区别与用法 #### 1. **RDD(弹性分布式数据集)** - **核心特点**: - **低层次API**:RDD是Spark最基础的抽象,提供细粒度的控制(如分区、容错等)[^4]。 - **无结构数据**:数据以分布式Java对象形式存储,Spark不了解其内部结构[^1]。 - **灵活性**:支持复杂的非结构化数据处理(如文本、图像)[^2]。 - **代码示例**: ```scala val rdd = sc.textFile("data.txt").flatMap(_.split(" ")) ``` - **缺点**:缺乏执行优化(如Catalyst优化器),不支持SQL操作[^1][^3]。 --- #### 2. **DataFrame** - **核心特点**: - **结构化数据**:以列形式组织数据,包含明确的Schema(列名、类型)[^1]。 - **高性能优化**:通过Catalyst优化器生成高效执行计划,支持Tungsten二进制存储。 - **SQL兼容**:可直接用Spark SQL查询,适合ETL、聚合分析等场景[^2]。 - **代码示例**: ```python df = spark.read.json("data.json") df.filter(df["age"] > 20).show() ``` - **缺点**:编译时无类型检查(如Python中列名错误需运行时发现)[^1]。 --- #### 3. **DataSet** - **核心特点**: - **强类型支持**:结合RDD的类型安全和DataFrame的优化(主要适用于Scala/Java)。 - **混合优势**:支持函数式编程(如`map`、`filter`),同时享受Catalyst优化[^4]。 - **统一接口**:在Spark 2.0后,DataFrame成为`DataSet[Row]`的别名。 - **代码示例**: ```scala case class Person(name: String, age: Int) val ds = spark.read.json("data.json").as[Person] ``` - **缺点**:对Python支持有限(Python无强类型特性)[^1]。 --- ### § 三者的区别总结 | **特性** | **RDD** | **DataFrame** | **DataSet** | |-------------------|-----------------------|-----------------------|-----------------------| | **数据形式** | 分布式对象集合 | 结构化表格(Row对象) | 强类型对象集合 | | **优化能力** | 无 | Catalyst + Tungsten | Catalyst + Tungsten | | **类型安全** | 运行时检查 | 无 | 编译时检查(Scala) | | **适用场景** | 非结构化数据、复杂逻辑| 结构化数据、SQL分析 | 类型安全的结构化数据 | --- ### § 使用场景建议 1. **RDD**:需要手动优化分区/容错,或处理非结构化数据(如日志清洗)。 2. **DataFrame**:结构化数据分析(如SQL查询、聚合统计),或需要跨语言使用(Python优先)。 3. **DataSet**:Scala/Java项目中需类型安全且高效的计算(如复杂业务逻辑)[^4]。 --- §§ 相关问题 §§ 1. 为什么DataFrame比RDD执行效率更高? 2. 如何将RDD转换为DataFrame? 3. DataSet在Scala中的类型安全是如何实现的? 4. Spark SQL是否支持直接操作DataSet? 5. 这三种数据结构在Spark版本演进中的关系是什么? --- : RDD一般和spark mlib同时使用,不支持sparksql操作。DataFrame提供了结构信息(schema),而RDD是分布式Java对象的集合。 [^2]: RDD、DataFrame和Dataset各有优势,需根据场景选择。DataFrame以列形式组织数据,支持更高级的抽象。 : DataFrame允许添加数据结构到分布式数据集合,类似于关系数据库的表。 : RDD、DataFrame、DataSet分别对应Spark 1.0、1.3、1.6版本,逐步演进为更高效和类型安全的抽象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值