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')