Spark Dataframe 以及SQL 操作

Spark 主要操作的数据类型是RDD,使用RDD进行数据统计其实就那么几个方法,大多都是通过RDD.map()来解决,但是RDD内部的数据就仅仅是数据,没有结构Schema, 所以每一"列" 就只能通过RDD里的位置就判断。 通过 spark 提供的 Datafram API 可以提供table格式的数据,方便进行数据分析。


更重要的是 Spark更先进的库 pyspark.ML(我用pyspark实现)API处理的数据格式是dataframe,如果想使用spark ML,就需要Datafram 来准备


先看看RDD:

每一个字段在RDD内部存在于不同的位置,但是检索起来就很麻烦

 

创建DataFrame

SparkSession是 Spark Context, SqlContext, HiveContext 的入口

#生成SparkSession
sqlContext = SparkSession.builder.getOrCreate()

#生成Row数据类型,为每一个RDD内的数据定义数据类型
from pyspark.sql import Row
user_Rows = userRDD.map(lambda p:
                            Row(
                                userId = int(p[0]),
                                age = int(p[1]),
                                gender = p[2],
                                occupation = p[3],
                                zipcode = p[4]
                            )
                       )
user_Rows.take(5)

通过Row生成Dataframe

Spark SQL 操作

使用SQL操作, 需要把dataframe注册生成临时表

user_df.registerTempTable('user')

接下来就可以使用SQL语句对临时表User进行操作了

sqlContext.sql(
    """
        select age,gender,occupation from user where age < 50 order by age limit 5
    """
).show(10)

 

Select 部分字段

1. 直接操作Datafram

# Dataframe.select方法
user_df.select('userid','occupation',"userId").show(10)

#pandas 写法 麻烦
user_df[user_df['userid'],user_df['occupation'],user_df['userId']].show(5)

2. SQL语句(sqlContext 就是创建的SparkSession, SparkSession.sql())

sqlContext.sql('select userid,occupation,gender from user').show(5)

添加字段(添加列)

#DataFrame
# .alias 为字段添加别名
df.select('userid','occupation','gender','age',(2019-df.age).alias("BOD")).show(5)


#SQL语句
sqlContext.sql("""
    select userid,occupation,gender,age,2019-age BOD from user order by BOD
""").show(5)

筛选数据

1.Datafram.filter()方法,多个filter 等于 and

df.filter('occupation="engineer"').filter("gender='M'").filter("age='70'").show(20)

2. 单个filter,条件用&,|进行连接

df.filter((df.occupation=='engineer')&(df.gender=='M')&(df.age==70)).show()

3.SQL方法

sqlContext.sql(
"""
select age,gender,occupation,userId,zipcode from user where age==70 and gender="M" and occupation='engineer'
""").show()

排序Order By

RDD数据使用takeOrdered(个数,key)来排序

userRDD.takeOrdered(10,key=lambda x:int(x[1]))

1.Dataframe

使用 Dataframe.select().orderBy() 方法

df.select('userid','occupation','gender','age').orderBy('age').show(5)

#降序
df.select('userid','occupation','gender','age').orderBy('age', ascending=0).show(5)

#多个字段排序,age降序,age相同时gender升序
df.select('userid','occupation','gender','age').orderBy(['age','gender'],ascending=[0,1]).show(5)

2 SQL: Order By 

 

Group By

RDD:用reduceByKey

DataFrame:用groupby

#RDD
userRDD.map(lambda x: (x[2],1)).reduceByKey(lambda x,y:x+y).filter(lambda x: x[1]>500).take(10)



#SQL方法
sqlContext.sql("""
select gender, count(gender) counts from user group by gender having counts>500
""").show()


#Dataframe
user_df.select(['gender','age']).groupby('gender').count().filter(col("count")>500).show()

Join

SQL语句

#SQL语句
sqlContext.sql("""
select z.state, count(*) from user u left join zipcode_table z on u.zipcode = z.zipcode 
where u.age < 50
group by z.state
""").show()

Dataframe

Join的Dataframe方法要生成一个新的dataframe然后进行操作

joined_df = user_df.join(zipcode_df,\
                        user_df.zipcode == zipcode_df.zipcode,'left_outer')

然后在通过filter,groupby进行筛选

joined_df.filter("state='NY'").show(10)

+---+------+-------------+------+-------+----------------+-----+-------+-----------+
|age|gender|   occupation|userId|zipcode|            city|state|zipcode|zipcodeType|
+---+------+-------------+------+-------+----------------+-----+-------+-----------+
| 29|     M|        other|   478|  10019|        NEW YORK|   NY|  10019|   STANDARD|
| 22|     F|   healthcare|   405|  10019|        NEW YORK|   NY|  10019|   STANDARD|
| 22|     M|      student|   327|  11101|LONG ISLAND CITY|   NY|  11101|   STANDARD|
| 48|     M|     educator|   656|  10314|   STATEN ISLAND|   NY|  10314|   STANDARD|
| 27|     F|       writer|   617|  11201|        BROOKLYN|   NY|  11201|   STANDARD|
| 35|     F|        other|   760|  14211|         BUFFALO|   NY|  14211|   STANDARD|
| 30|     F|       writer|   557|  11217|        BROOKLYN|   NY|  11217|   STANDARD|
| 27|     M|    marketing|   806|  11217|        BROOKLYN|   NY|  11217|   STANDARD|
| 32|     F|        other|   155|  11217|        BROOKLYN|   NY|  11217|   STANDARD|
| 23|     M|administrator|   509|  10011|        NEW YORK|   NY|  10011|   STANDARD|
+---+------+-------------+------+-------+----------------+-----+-------+-----------+
only showing top 10 rows

GroupBy 方法

GroupByState_df = joined_df.groupBy('state').count().filter(col("count")>20)

GroupByState_df.show(5)

+-----+-----+
|state|count|
+-----+-----+
|   MN|   78|
| null|   35|
|   VA|   27|
|   MI|   23|
|   WI|   22|
+-----+-----+
only showing top 5 rows

将Spark DataFrame 转化为 pandas Dataframe

 

toPandas()方法

GroupByState_df = GroupByState_df.toPandas().set_index('state')

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值