pandas vs pyspark code index

137 阅读3分钟

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('原始列名')给他改回去。 需要pyspark重命名列名

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)