ceil函数_pyspark常用函数

本文详细介绍了PySpark中的一些关键函数,包括如何创建dataframe、基础操作、日期处理、统计计算、窗口函数以及数据转换如pivot进行行转列和列转行的操作。通过对这些函数的理解和应用,可以更有效地处理大规模数据。

a8c2224e810cb5a7c76a32f4c9d726f2.png

一、创建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 (重塑后的列名)”) 注意保持数据格式一致


#【注意:】
#【进行列传行的操作之前,先将数值指标转换为同一类型才可以进行以下列转行的操作,不然会报错!!!!!】
<think>我们有一个PySpark DataFrame,其中包含一个名为'value'的列。我们想要对该列进行以下操作:整列除以3,然后对结果向上取整。 在PySpark中,我们可以使用内置的函数来实现。具体步骤如下: 1. 导入必要的函数:`ceil` 用于向上取整,`col` 用于引用列。 2. 使用`withColumn`方法对'value'列进行运算,并将结果保存到新列(或者覆盖原列)。 注意:如果我们要覆盖原来的'value'列,则使用相同的列名;否则,指定一个新的列名。 示例代码: 假设我们有一个DataFrame `df`,其中包含'value'列。 我们可以这样写: from pyspark.sql import functions as F df = df.withColumn('value', F.ceil(F.col('value') / 3)) 或者,如果我们想保留原列,可以创建一个新列: df = df.withColumn('new_value', F.ceil(F.col('value') / 3)) 但是根据问题,我们要求对整列进行操作,并且没有说明是否覆盖,通常我们可以选择覆盖原列或创建新列。这里按照问题要求,我们直接对'value'列进行修改(即覆盖)。 另外,注意除法运算:在PySpark中,除法使用`/`,它会返回浮点数结果,然后我们使用`ceil`向上取整。 但是,如果原始列是整数类型,除以3之后会变成浮点数,然后向上取整后还是浮点数。如果我们希望结果是整数类型,可以再使用`cast`转换为整数类型,但注意`ceil`函数返回的是浮点数,所以如果需要整数,可以再转换。不过,向上取整后的浮点数表示整数,所以也可以直接转换。 不过,问题要求向上取整,所以直接使用`ceil`即可,类型是浮点型。如果要求整数类型,可以再转换。 因此,如果我们需要整数类型的结果,可以: df = df.withColumn('value', F.ceil(F.col('value') / 3).cast('integer')) 或者使用`F.ceil(...).astype('int')`也可以。 但是,根据问题,只要求除以3并向上取整,并没有指定类型,所以我们可以按浮点数保留,或者按整数。通常向上取整后是整数,所以转为整数更合理。 我们这里按照整数处理,因为取整后就是整数。 所以,最终代码可以写为: from pyspark.sql import functions as F df = df.withColumn('value', F.ceil(F.col('value') / 3).cast('integer')) 或者,我们可以使用PySpark SQL的内置函数,另一种写法是使用表达式字符串,但这里使用函数的方式更常见。 另外,还有一种写法是使用`expr`函数: df = df.withColumn('value', F.expr("ceil(value / 3)").cast('integer')) 但推荐使用第一种方式,因为更符合PySpark的编程风格。 注意:如果数据量很大,这些操作都是分布式执行的。 下面我们给出完整的代码示例:</think>在 PySpark 中,对 DataFrame 的 `value` 列执行除以 3 并向上取整的操作,可以通过以下步骤实现: ### 操作步骤 1. **导入所需函数**: ```python from pyspark.sql import functions as F ``` 2. **执行列操作**: - 使用 `withColumn()` 修改列 - 通过 `F.col("value") / 3` 实现除法 - 用 `F.ceil()` 进行向上取整 ```python # 覆盖原列(修改后仍命名为 'value') df = df.withColumn("value", F.ceil(F.col("value") / 3)) # 或创建新列(保留原列) df = df.withColumn("value_ceil", F.ceil(F.col("value") / 3)) ``` ### 完整示例 ```python from pyspark.sql import SparkSession from pyspark.sql import functions as F # 创建 SparkSession spark = SparkSession.builder.appName("CeilExample").getOrCreate() # 示例数据 data = [(10,), (7,), (15,), (22,)] df = spark.createDataFrame(data, ["value"]) # 执行操作:value 列除以 3 后向上取整 df_transformed = df.withColumn("value_ceil", F.ceil(F.col("value") / 3)) # 显示结果 df_transformed.show() ``` ### 输出结果 ``` +-----+----------+ |value|value_ceil| +-----+----------+ | 10| 4.0| | 7| 3.0| | 15| 5.0| | 22| 8.0| +-----+----------+ ``` ### 关键说明 1. **向上取整规则**: - `ceil()` 总是向正无穷方向取整 - 例如:`7/3≈2.333 → ceil(2.333)=3.0` 2. **数据类型处理**: - 整数列除以 3 会隐式转为 `DoubleType` - 结果列默认为浮点型(可通过 `.cast("integer")` 转整数) 3. **分布式计算**: - 此操作在 Spark 集群上并行执行,适合大规模数据[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值