1、Quickstart: DataFrame
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
方法一:
from datetime import datetime, date
import pandas as pd
from pyspark.sql import Row
df = spark.createDataFrame([
Row(a=1, b=2., c='string1', d=date(2000, 1, 1), e=datetime(2000, 1, 1, 12, 0)),
Row(a=2, b=3., c='string2', d=date(2000, 2, 1), e=datetime(2000, 1, 2, 12, 0)),
Row(a=4, b=5., c='string3', d=date(2000, 3, 1), e=datetime(2000, 1, 3, 12, 0))
])
df
或
df = spark.createDataFrame([
(1, 2., 'string1', date(2000, 1, 1), datetime(2000, 1, 1, 12, 0)),
(2, 3., 'string2', date(2000, 2, 1), datetime(2000, 1, 2, 12, 0)),
(3, 4., 'string3', date(2000, 3, 1), datetime(2000, 1, 3, 12, 0))
], schema='a long, b double, c string, d date, e timestamp')
df
方法二:从pandas引
pandas_df = pd.DataFrame({
'a': [1, 2, 3],
'b': [2., 3., 4.],
'c': ['string1', 'string2', 'string3'],
'd': [date(2000, 1, 1), date(2000, 2, 1), date(2000, 3, 1)],
'e': [datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 2, 12, 0), datetime(2000, 1, 3, 12, 0)]
})
df = spark.createDataFrame(pandas_df)
df
方法三:from rdd
rdd = spark.sparkContext.parallelize([
(1, 2., 'string1', date(2000, 1, 1), datetime(2000, 1, 1, 12, 0)),
(2, 3., 'string2', date(2000, 2, 1), datetime(2000, 1, 2, 12, 0)),
(3, 4., 'string3', date(2000, 3, 1), datetime(2000, 1, 3, 12, 0))
])
df = spark.createDataFrame(rdd, schema=['a', 'b', 'c', 'd', 'e'])
df
Viewing Data
df.show()
df.printSchema()
df.show(1, vertical=True) # 竖着,翻过来显示
df.select("a", "b", "c").describe().show()
df.collect() # 将分布式数据作为Python中的本地数据收集到driver。它会将所有数据从执行程序收集到驱动程序端
df.take(1) # 取前1个
df.tail(5) # 取后5个
df.toPandas() # 转换回pandas。 toPandas还将所有数据收集到驱动程序端,当数据太大而无法放入驱动程序端时,这些数据很容易导致内存不足错误。
Selecting and Accessing Data
df.a
from pyspark.sql import Column
from pyspark.sql.functions import upper
type(df.c) == type(upper(df.c)) == type(df.c.isNull())
df.select(df.c).show()
df.withColumn('upper_c', upper(df.c)).show()
df.filter(df.a == 1).show()
为了更高效的 Spark 计算,我们将启用基于 arrow 的列式数据传输。
spark.conf.set('spark.sql.execution.arrow.enabled', 'true')
Applying a Function
PySpark Pandas UDF(用户定义函数)(一个用于在 Spark 集群上分发 Python 函数的框架)
“Pandas UDF 是用户定义的函数,由 Spark 执行,使用 Arrow 传输数据,Pandas 执行数据,允许向量化操作。Pandas UDF 是使用pandas_udf
作为装饰器或包装函数来定义的,不需要额外的配置。Pandas UDF 通常表现为常规的 PySpark 函数 API。”
Pandas UDF 分组数据允许在数据集的每一组中进行操作。由于 spark 中的分组操作是跨集群节点计算的,因此我们可以以允许在不同节点计算不同模型的方式操作我们的数据集。
import pandas as pd
from pyspark.sql.functions import pandas_udf
@pandas_udf('long')
def pandas_plus_one(series: pd.Series) -> pd.Series:
# Simply plus one by using pandas Series.
return series + 1
df.select(pandas_plus_one(df.a)).show()
# mapInPandas允许用户直接使用pandas DataFrame中的API,而无需任何限制,例如结果长度。
def pandas_filter_func(iterator):
for pandas_df in iterator:
yield pandas_df[pandas_df.a == 1]
df.mapInPandas(pandas_filter_func, schema=df.schema).show()
Grouping Data
df = spark.createDataFrame([
['red', 'banana', 1, 10], ['blue', 'banana', 2, 20], ['red', 'carrot', 3, 30],
['blue', 'grape', 4, 40], ['red', 'carrot', 5, 50], ['black', 'carrot', 6, 60],
['red', 'banana', 7, 70], ['red', 'grape', 8, 80]], schema=['color', 'fruit', 'v1', 'v2'])
df.show()
df.groupby('color').avg().show()
def plus_mean(pandas_df):
return pandas_df.assign(v1=pandas_df.v1 - pandas_df.v1.mean())
df.groupby('color').applyInPandas(plus
pyspark入门 中文官方文档
于 2022-10-26 16:02:32 首次发布