
一、创建dataframe
1、直接创建Dataframe spark.createDataFrame(data, schema=None, samplingRatio=None),直接创建,其中:
data是行或元组或列表或字典的RDD、list、pandas.DataFrame:
df = spark.createDataFrame([
(1, 144.5, 5.9, 33, 'M'),
(2, 167.2, 5.4, 45, 'M'),
(3, 124.1, 5.2, 23, 'F'),
(4, 144.5, 5.9, 33, 'M'),
(5, 133.2, 5.7, 54, 'F'),
(3, 124.1, 5.2, 23, 'F'),
(5, 129.2, 5.3, 42, 'M'),
], ['id', 'weight', 'height', 'age', 'gender'])2、从字典创建
df = spark.createDataFrame([{'name':'Alice','age':1},
{'name':'Polo','age':1}])3、读取的方式创建
df = spark.read.parquet("brand_base/*")
df = spark.read.csv('/user/python/test.csv',header=True)
df = spark.read.json('user/python/people.json')
df = spark.read.text('user/python/test.txt', wholetext=True)二、基础操作
1、查看列名:color_df.columns
2、查看字段类型:printSchema()
3、查看行列数:print((df.count(), len(df.columns)))
4、前n行:df.limit(3).show() 获取指定DataFrame的前n行记录,得到一个新的DataFrame对象,limit方法不是Action操作
5、重命名列名:withColumnRenamed('原始名','新名字')
6、选择列:
select('列名','列名','列名')
selectExpr('customer_id as el_customer_id','md5','store as el_store','prediction')
selectExpr:可以对指定字段进行特殊处理 ,可以直接对指定字段调用UDF函数,或者指定别名等
7、范围选择:df.where(col('date').between('start','end'))
df.where(col('date') >= lit('2020-01-01'))
9、分组统计:df.groupby('store','gender').agg(sum('amount'),countDistinct('id'))
10、新增一列:df.withColumn('newColname', lit('哈哈哈'))
11、排序:df.orderBy(col('col1'),col('col2'),col('col3').desc()),默认是升序,可以加desc()来降序排
df.sort(col('col1').desc(),col('col2').asc())
df.sort(col('col1'),ascending = False)
12、join操作:A.join(B,['key1','key2','key3'],'left'),left,inner,left_anti,full ,横向拼接
13、union操作:A.union(B) , 纵向拼接,表的schema要一样才可以
14、when操作:df.withColumn('tap', when((col('age') == 20) & (col('gender') == lit('F')) , lit(1)).otherwise(lit(2)))
15、填充缺失值:df.fillna(0),df.fillna('哈哈'),df.na.fill('wz')
16、删除缺失值所在行:dropna(),或者na.drop()
17、去空格:df.withColumn('name',trim(col('name')))【去除前后空格】
18、去重:
按照部分字段去重:df.groupby('id','product').count().drop('count')
全字段去重:df.dropDuplicates()
三、日期函数
1、获取当前日期:current_date()
2、获取当前日期和时间:current_timestamp(),带时间戳
3、获取日期中的年月日:
df.withColumn('year',year(col('a')))
df.withColumn('month',month(col('a')))
df.withColumn('day',dayofmonth(col('a')))
df.withColumn('week',dayofweek(col('a')))
df.withColumn('day_num',dayofyear(col('a')))
【获取对应的年,月,日,一周内第几天,一年内第几天】
4、获取日期对应的季度:quarter(col('a'))
5、获取本月的最后一个日期、第一个日期:
对应的月份的第一个日期:trunc('purchase_date', 'month')
对应的月份的最后一个日期:last_day(col('日期'))
6、日期格式转换:date_format(col('待转换字段), '目标格式'),例如,date_format('a', 'MM/dd/yyy')
7、字符转日期:
转日期:to_date(col('待转换字段))
带时间的日期:to_timestamp(col('待转换字段))
8、日期加减:
date_add(col('date'), 1).alias('d-add'),日期加一天
date_sub(col('date'), 1).alias('d-sub'),日期减一天
9、月份加减:
df.withColumn('new_month',add_months(col('month'), 1),月份加一月
10、日期差,月份差:
日期差:datediff(col('日期一'), col('日期二'))
月份差:months_between(col('日期一'), col('日期二'))
四、统计函数
1、取整函数:
向上取整:ceil(),ceil(3.4)=4
截取整数部分:trunc
向下取整:floor,floor(3.4)=3
四舍五入取整:rint
2、保留小数:round('a', 2),保留2位小数
3、最值:min(col('amount')), max(col('amount'))
4、求和:sum('amount')
5、计数:countDistinct('purchase_date'),count('purchase_date')
6、分位数:
quantiles = df.approxQuantiles(col('age'),[0.25,0.75],0.05)
IQR = quantiles[1] - quantitles[0]
min_value = quantitles[0] - 1.5 * IQR
max_value = quantitles[1] + 1.5 * IQR
7、描述统计:df.describe()
五、开窗函数
1、分组排序(增加排名rank):
rank, dense_rank, row_number 都是把表中的行按分区内的排序标上序号,但有一点差别:
rank:可以生成不连续的序号,比如按分数排序,第一第二都是100分,第三名98分,那第一第二就会显示序号1,第三名显示序号3(排名重复占位)
dense_rank: 生成连续的序号,第一第二并列显示序号1,第三名会显示序号2(排名重复不占位)。
row_number: 顾名思义就是行的数值,第一第二第三将会显示序号为1,2,3(排名不重复占位)。
写法,以row_number()为例:
df.withColumn('rank',row_number().over(Window.partitionBy('source').orderBy(col('amount').desc()))) 2、分组计数
df.withColumn('num',countDistinct('id').over(Window.partitionBy(['source',type']).orderBy(col('source').desc(),col('type')))3、分组累积求和 '
df.withColumn('sales_accumulate',sum(col('quantity')).over(Window.partitionBy(['source','year']).orderBy(col(month'))))六、行转列
pivot,实现行转列 逻辑如下:
1、按照共有字段分组,本例中是groupby('class','month')
2、使用pivot函数进行透视,第一个参数表示对这个字段进行转换,第二个参数来明确指定使用哪些数据项,本例中: pivot('year',year_list)的year 表明对这个字段进行转换,year_list指明用'year'列中的2018及2019的数据
3、汇总数字字段,本例中是avg_score 为便于理解,将没有数据显示的部分填充为0:fillna(0),这样也便于在此基础上进行相关计算
year_list = [2018,2019]
result = data
.groupby('class','month')
.pivot('year',year_list)
.agg(sum('avg_score'))
.fillna(0)
.withColumn('uprate',(col('2019')-col('2018'))/col('2018'))
.orderBy(col('class'),col('month'))七、列转行
#方法一:
#Spark SQL中,行转列有内建的PIVOT函数可用,列转行需要借助stack函数实现
#通过DataFrame的createOrReplaceTempView("tablename")将其创建或者替换一个临时视图,即表tablename。就可以用spark.sql方法在表tablename上运行SQL语句了。
df.createOrReplaceTempView('df1')
res_unpivot = spark.sql("""
SELECT
class
,year
,stack(2,'tt_score',tt_sales,'avg_score',avg_score) as (index,values)
FROM df1""")
#class、year为要保留的列,stack中第一个参数为需要列转行的列数,紧跟着是列名及值,列名要用引号引起来!!!
#方法二:
df.selectExpr('class','year',"stack(2,'tt_score',tt_score,'avg_score',avg_score) as (index,values)")
#函数参数说明:xx.selectExpr(保留的列,”stack (待重塑列的列数,原始列名,对应列值) as (重塑后的列名)”) 注意保持数据格式一致
#【注意:】
#【进行列传行的操作之前,先将数值指标转换为同一类型才可以进行以下列转行的操作,不然会报错!!!!!】
本文详细介绍了PySpark中的一些关键函数,包括如何创建dataframe、基础操作、日期处理、统计计算、窗口函数以及数据转换如pivot进行行转列和列转行的操作。通过对这些函数的理解和应用,可以更有效地处理大规模数据。
4982

被折叠的 条评论
为什么被折叠?



