Python Spark SQL、DataFrame基本操作

Python Spark SQL、DataFrame基本操作

以下所有操作均在Spark2.0版本下

通过文件创建DataFrame

# 文件内容应是跟Python DataFrame形式一样,不是的话需进行转化
userRDD = sc.textFile(filePath)
# 创建sqlContext,入口
sqlContext = SparkSession.builder.getOrCreat()
# 定义DataFrames的每一个字段名和数据类型
from pyspark.sql import Row
user_Rows = userRDD.map(lambda p:
  Row(
    userid=int(p[0]),
    age=int(p[1]),
    gender=p2,
    occupation=p[3],
    zipcode=p4
  )
)
# 将生成好的Rows转换为DataFrame
user_df = sqlContext.createDataFrame(user_Rows)
# 可以通过.printSchema() 方法查看DataFrame的Schema
# 创建别名
df = user_df.alias('df')

使用Spark SQL

# 创建好了DataFrame之后,用其注册临时表,就可以在DataFrame上使用SQL语句了
user_df.registerTempTable('user_table')
# 写SQL语句,用show()方法显示
sqlContext.sql("select * from user_table").show()
# 这样我们可以使用一般的SQL语句对DataFrame进行分析

SELECT显示部分字段

# RDD
userRDDnew = userRDD.map(lambda p: (p[0], p[2], p[3], p[5]))
# DataFrame
user_df.select('userid', 'occupation', 'gender').show(5)
user_df.select(user_df.userid, user_df.occupation, user_df.gender).show(5)
df.select(df.userid, df.occupation, df.gender).show(5)  # df是别名
# Spark sql
sqlContext.sql('SELECT user_id, gender, occupation FROM user_table')

增加计算字段

# RDD
userRDDnew = userRDD.map(lambda p: (p[0], p[2], p[3], 2016 - p[5])) # 增加了一个不属于原来数据集的字段
# DataFrame 增加字段并改名
user_df.select('userid', 'occupation', 'gender', (2021-df.age).alias('birthyear')).show(5)
# Spark sql
sqlContext.sql('SELECT user_id, gender, occupation, age birthyear FROM user_table')

筛选数据

# RDD
userRDD.filter(lambda r: r[3]=='technician' and r[2]=='M' and r[1]=='24').take(5)
# DataFrame
user_df.filter('occupation="technician"' and 'gender="M"' and 'age="24"').show()
df.filter((df['occupation']=='techician') & (df['gender']=='M') & (df['age']==24)).show()
# Spark sql
sqlContext.sql("SELECT * FROM user_table where occupation='technician' and gender='M' and age=24")

数据排序

# RDD  按年龄升序排序,取出前十个
userRDD.takeOrdered(10, key=lambda x: int(x[1]))
# 这是降序
userRDD.takeOrdered(10, key=lambda x: -1 * int(x[1]))
# DataFrame 按年龄升序
user_df.orderBy('age').show(5)
# 降序
user_df.orderBy('age',ascending=0).show(5)
# Spark sql 按年龄升序
sqlContext.sql('SELECT user_id, gender, occupation FROM user_table ORDER BY age').show(5)
# 降序
sqlContext.sql('SELECT user_id, gender, occupation FROM user_table ORDER BY age DESC').show(5)

多个字段排序

# RDD  先按年龄降序排序,再按性别升序排序,取出前十个
userRDD.takeOrdered(10, key=lambda x: (-int(x[1]), x[2]))
# DataFrame 先按年龄升序排序,再按性别升序排序
user_df.orderBy(['age', 'gender'], ascending=[0, 1]).show(5)
user_df..orderBy(df.age.desc(), df.gender).show(5)
# Spark sql 先按年龄升序排序,再按性别升序排序
sqlContext.sql('SELECT user_id, gender, occupation FROM user_table ORDER BY age DESC, gender').show(5)

显示不重复的数据

# RDD 性别不重复
userRDD.map(lambda r: r[2]).distinct()
# 性别年龄的组合不重复
userRDD.map(lambda r: r[1], r[2]).distinct()
# DataFrame
user_df.select('gender').distinct().show()
user_df.select('gender', 'age').distinct().show()
# Spark sql
sqlContext.sql('SELECT distinct gender FROM user_table').show(5)
sqlContext.sql('SELECT distinct gender,age FROM user_table').show(5)

分组统计

# RDD 在RDD中要进行数据的分组统计必须使用map/reduce,例如按性别统计数据
userRDD.map(lambda r: (r[2], 1)).reduceByKey(lambda x,y: x + y).collect()
# 按职业和性别来统计数据
userRDD.map(lambda r: ((r[2], r[2]), 1)).reduceByKey(lambda x,y: x + y).collect()
# DataFrame
df.groupBy('gender').count().show()
df.groupBy('gender', 'occupation').count().show()
# 还有一种crosstab,顾名思义是列一个交叉表
df.stats.crosstab('gender', 'occupation').show()
# Spark sql
sqlContext.sql('SELECT gender, count(*) counts FROM user_table GROUP BY gender').show()
sqlContext.sql('SELECT gender, count(*) counts FROM user_table GROUP BY gender, occupation').show()

Join 连接数据

# Spark sql 其中user_table后的u和other_table后的o是别名
sqlContext.sql('SELECT * FROM user_table u LEFT JOIN other_table o on u.field= o.field').show()
# DataFrame
joined_df = user_df.join(other_df, user_df.field==other_df.field, 'left_outer')
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值