pyspark(二)

pyspark dataframe

select()collect()

select()就是列名进行选择,collect()就是对数据的最终结果或者中间结果进行收集,非常类似于Java的Stream流的collect(),对RDD跟DataFrame的进行校验,应该避免在大的数据集中使用collect()防止内存被爆掉。

filter()

这里的案例除非是特别创建,否则都是pyspark(一)的数据
filter就是对一个dataframe进行筛选,这里一般是列筛选,某一个列大于或者小于,包含或者startswith等等根据列的值进行筛选

from pyspark.sql import SparkSession
import pandas as pd
import pyspark.sql.functions as F
import pyspark.sql.types as T

# 创建spark与dataframe
spark=SparkSession.builder.appName("alpha").getOrCreate()
df=spark.read.csv(china_order_province_path,header=True)
df=spark.createDataFrame(data=[[],[]],shema=column_name)

#dataframe.filter(condition)这里进行筛选,很类似于pandas里的DataFrame(df["col_name"]><=等等) isin startswith,contains,like等等,这边进行筛选的方式其实有很多,自己看着用。
df_filtered=df.filter(df["col_name"]>|< |== |contains()| in col_lists)
withColumn() withColumnRename(old_name,new_name)

pandas 对某一列进行处理,这个跟pandas里的df.apply(lambda x:x[“col_name”]+“end”,axis=1)

df=df.withColumn("new_col_name",df["col_name"].cast(T.StringType()))
#一个常用的案例
spark = SparkSession.builder.appName("beta").getOrCreate()
df=spark.read.csv(china_order_province_path,header=True)
@udf
def exchange_city_level(input_string):
    if "三" in input_string:
        return "3"
    elif "二" in input_string:
        return "2"
    elif "一" in input_string:
        return "1"
    else:
        return "18"

df = df.withColumn("city_level", exchange_city_level(df['城市等级']))
**有时间测试一下直接使用匿名函数lambda来进行,对一些很小的数据处理能很快速解决,也比较好看,这样的方式太过于复杂。**

一个小tips,不知道是spark环境的问题,还是版本问题,在处理很小数据过程中,spark表现的非常的卡顿,处理后的dataFrame.toPandas()有时候也不是很好用,所以可以直接使用collect().__len__()来快速看结果是否,而也不需要show(10)等等
drop&dropDuplicates()&distinct()

这个跟pandas是一致的去除某一列drop(col_name_list),dropDuplicates(col_name_list),distinct()

    data = [("James", "Sales", 3000),
            ("Michael", "Sales", 4600),
            ("Robert", "Sales", 4100),
            ("Maria", "Finance", 3000),
            ("James", "Sales", 3000),
            ("Scott", "Finance", 3300),
            ("Jen", "Finance", 3900),
            ("Jeff", "Marketing", 3000),
            ("Kumar", "Marketing", 2000),
            ("Saif", "Sales", 4100),
            ("Saif", "Sales", 4200),
            ]
    data_columns = ["employee_name", "department", "salary"]
    df_beta = spark.createDataFrame(data=data, schema=data_columns)
    df_beta.collect().__len__()
    df_beta = df_beta.distinct()
    df_test = df_beta.dropDuplicates(subset=['employee_name', "department"])
    df_test.collect().__len__()
其实这么一大段就一个意思,distinct()是要所有行的数据都要一样才去除,dropDuplicates(subset=["col_a","col_b"]),col_a,与col_b的列一样就可以去除。也或者可以直接drop(col_name_list)
统计:groupby(col_name_list).agg(F.func(“col_a”).alias(“new_col_a”),…)
def spark_group_by():
    """
    group_by跟pandas里的几乎一样,group_by其实就是统计基准列(可以catalog),然后统计数据列(value)的max,min,avg,sum,
    :return:
    """
	import pyspark.sql.functions as func
    spark = SparkSession.builder.appName("alpha").getOrCreate()

    df = spark.read.csv(path=r"D:\***\china_order_province.csv"
                        , header=True, encoding='utf-8')
    df_grouped = df.groupBy(['省']).agg(func.avg("包邮率").alias("平均包邮率"),
                                        func.sum("订单数").alias("总共订单数"),
                                        func.max("常住人口2010").alias("省内最大城市人口"),
                                        func.max("订单数").alias("最大订单数"))
    temp_df = df_grouped.toPandas()
    return df, df_grouped

多表统计 df_a.join(df_b,df_a.col_name=df_b.col_name,how=“inner”)

这里相对于pandas好像多了一个semi的办法,这里其实就是a表在b表中存在的进行筛选,并不进行多表合并。

    
    spark = SparkSession.builder.appName("test").getOrCreate()
    emp = [(data)]
    empColumns = [col_name_list]
    dept = [data]
    deptColumns=[col_name_list]
    result = empDF.join(deptDF, empDF['emp_dept_id'] == deptDF["dept_id"], how="left_semi")
    
transform

可能是因为我spark的版本的缘故,我没有办法直接使用这个,但是可以通过一个function_list(),然后使用一个for循环来进行遍历。

import pandas as pd
from pyspark.sql import SparkSession
import pyspark.sql.functions as F
import pyspark.sql.types as T


def upper_columns(df):
    @F.udf(returnType=T.StringType())
    def upper_low_case(string):
        return string.upper()

    """给random columns 转换大小写"""
    df = df.withColumn("new_random", upper_low_case(df['random']))
    return df


def mail_free_ratio(df):
    """给包邮率进行一个简单的分级"""

    @F.udf(returnType=T.StringType())
    def level_three(val):
        try:
            value = float(val)
        except ValueError as e:
            value = 0
        if value >= 0.95:
            return "high"
        elif (value >= 0.85) & (value < 0.95):
            return "middle"
        elif (value < 0.85) & (value >= 0):
            return "low"
        else:
            return "none"

    df = df.withColumn("mail_level", level_three(df['包邮率']))
    return df


def exchange_level(df):
    @F.udf(returnType=T.StringType())
    def exchange_value(input_string):
        if "三" in input_string:
            return "3"
        elif "二" in input_string:
            return "2"
        elif "一" in input_string:
            return "1"
        else:
            return "18"

    df = df.withColumn("city_level", exchange_value(df['城市等级']))
    return df


def dataframe_alpha():
    """本来打算使用spark里的transform这个东西,有点像stream流的东西
    结果2.4.5这个版本不支持,抽空把版本升级一下,
    其实也可以通过一个function的list来对dataframe进行遍历,使用__call__()来依此调用,其实有点像stream流的意思了,
    有趣的python"""
    spark = SparkSession.builder.appName("alpha").getOrCreate()
    df = spark.read.csv(r'D:\***\china_order_province_beta.csv',
                        header=True, encoding="utf-8")
    # df.withColumn
    func_list = [exchange_level, mail_free_ratio, upper_columns]
    for ele in func_list:
        df = ele.__call__(df)

    df.show()

map() flatMap()

在对一个col或者几个col进行计算,结果不保存为dataFrame形式的时候,可以尝试将dataFrame转换为rdd然后来进行处理。

    data = {
        "col_a": ['abc_alpha', 'kmn_beta', 'xyz_gamma'],
        "col_b": ['abc_delta', 'kmn_epsilon', 'xyz_zeta']
    }
    pandas_df = pd.DataFrame(data)
    spark = SparkSession.builder.appName("test_beta").getOrCreate()
    df = spark.createDataFrame(data=pandas_df)
    rdd = df.rdd.flatMap(lambda x: x['col_a'].split("_")).collect()
    rdd_beta = df.rdd.map(lambda x: x['col_b'].split("_")).collect()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值