1.Pyspark简介
Apache Spark是一个闪电般快速的实时处理框架。它进行内存计算以实时分析数据。由于Apache Hadoop MapReduce仅执行批处理并且缺乏实时处理功能,因此它开始出现。因此,引入了Apache Spark,因为它可以实时执行流处理,也可以处理批处理。
Apache Spark是Scala语言实现的一个计算框架。为了支持Python语言使用Spark,Apache Spark社区开发了一个工具PySpark。我们可以通过Python语言操作RDDs
RDD简介
RDD (Resiliennt Distributed Datasets)
•RDD = 弹性 + 分布式 Datasets
1)分布式,好处是让数据在不同工作节点并行存储,并行计算
2)弹性,指的节点存储时,既可以使用内存,也可以使用外存
•RDD还有个特性是延迟计算,也就是一个完整的RDD运行任务分成两部分:Transformation和Action
Spark RDD的特性:
分布式:可以分布在多台机器上进行并行处理 弹性:计算过程中内存不够时,它会和磁盘进行数据交换 基于内存:可以全部或部分缓存在内存中 只读:不能修改,只能通过转换操作生成新的 RDD
2. pandas与pyspark操作对照
1)读写文件read_csv,to_csv
df = spark.read.csv(path, sep=';')#读取
df.coalesce(n).write.mode('overwrite').csv(path, sep=';')#df转写为csv文件,to csv
df.show(3) #用来显示前3行
列指定分区(不一定用得到
df.partitionBy("department","state").write.mode('overwrite').csv(path, sep=';')
2) 统计describ,agg,groupBy
df.summary()一样 df.describe()一样
groupBy的B:注意小写变大写 (pandas中用来groupby的列名会自动成为索引,需要reset_index才能重新显示成列,而spark就不用管,就正常)
df.groupBy('department').agg({'employee': 'count', 'salary':'max', 'age':'mean'})
agg:在 PySpark 中,agg之后,列名会在结果dataframe中被重命名,需要.alias('原始列名')给他改回去。
df.groupBy('department').agg(F.count('employee').alias('employee'), F.max('salary').alias('salary'), F.mean('age').alias('age'))
3)创建df
df = spark.createDataFrame(data).toDF(*columns)
# 查看头2行
df.limit(2).show()
4)指定字段数据类型
from pyspark.sql.types import StructType,StructField, StringType, IntegerType
schema = StructType([ \
StructField("employee",StringType(),True), \
StructField("department",StringType(),True), \
StructField("state",StringType(),True), \
StructField("salary", IntegerType(), True), \
StructField("age", IntegerType(), True) \
])
df = spark.createDataFrame(data=data,schema=schema)
df.dtypes
# 查看数据类型
df.printSchema()
5)选择列、添加列
.select
columns_subset = ['employee', 'salary']
df.select(columns_subset).show(5)
添加行withColumn
seniority = [3, 5, 2, 4, 10]
df = df.withColumn('seniority', seniority)
6)选择行.iloc()→.take() or .limit()
df.take(2).head()
# 或
df.limit(2).head()
7)选择、过滤数据
import pyspark.sql.functions as F
# 方法1:基于filter进行数据选择
filtered_df = df.filter((F.col('salary') >= 90_000) & (F.col('state') == 'Paris'))
# 或者
filtered_df = df.filter(F.expr('(salary >= 90000) and (state == "Paris")'))
# 方法2:基于SQL进行数据选择
df.createOrReplaceTempView("people")
filtered_df = spark.sql("""
SELECT * FROM people
WHERE (salary >= 90000) and (state == "Paris")
""")
8)df拼接,concat的替代
两个df用union
# PySpark拼接2个dataframe
df_to_add = spark.createDataFrame([("Robert","Advertisement","Paris",55000,27)]).toDF(*columns)
df = df.union(df_to_add)
多个df拼接
# pyspark拼接多个dataframe
from functools import reduce
from pyspark.sql import DataFrame
def unionAll(*dfs):
return reduce(DataFrame.unionAll, dfs)
dfs = [df, df1, df2,...,dfn]
df = unionAll(*dfs)
9)lamda函数→F.udf
pandas
df['new_salary'] = df['salary'].apply(lambda x: x*1.15 if x<= 60000 else x*1.05)
pyspark
from pyspark.sql.types import FloatType
df.withColumn('new_salary', F.udf(lambda x: x*1.15 if x<= 60000 else x*1.05, FloatType())('salary'))
3. 可能用到的机器学习代码
1) 决策树
from pyspark.ml.classification import DecisionTreeClassifier
# 创建决策树模型
dt = DecisionTreeClassifier(featuresCol = 'features', labelCol = 'label', maxDepth = 3)
dt_model = dt.fit(train)
#查看决策树结构
print(dt_model._call_java('toDebugString'))
测试集
predictions = dt_model.transform(test)
predictions.printSchema()
#计算AUC值
from pyspark.ml.evaluation import BinaryClassificationEvaluator
evaluator = BinaryClassificationEvaluator()
evaluator.evaluate(predictions)
网格搜参
from pyspark.ml.tuning import ParamGridBuilder, CrossValidator
param_grid = (ParamGridBuilder()
.addGrid(dt.maxDepth, [1, 2, 6, 10])
.addGrid(dt.maxBins, [20, 40, 80])
.build())
# 设置五折交叉验证
cv = CrossValidator(estimator=dt, estimatorParamMaps=param_grid, evaluator=evaluator, numFolds=5)
# 运行cv
cv_model = cv.fit(train)
# 查看最优模型
print("numNodes = ", cv_model.bestModel.numNodes)
print("depth = ", cv_model.bestModel.depth)
五折交叉验证预测
# 使用五折交叉验证进行预测
predictions = cv_model.transform(test)
evaluator.evaluate(predictions)
2)随机森林
from pyspark.ml.classification import RandomForestClassifier
# 随机森林
rf = RandomForestClassifier(featuresCol = 'features', labelCol = 'label')
rf_model = rf.fit(train)
predictions = rf_model.transform(test)
predictions.printSchema()
selected = predictions.select("label", "prediction", "probability", "age", "occupation")
display(selected)
evaluator = BinaryClassificationEvaluator()
evaluator.evaluate(predictions)