升级 PySpark#
从 PySpark 4.0 升级到 4.1#
在 Spark 4.1 中,PySpark 停止了对 Python 3.9 的支持。
在 Spark 4.1 中,PySpark 对 PyArrow 的最低支持版本从 11.0.0 提高到了 15.0.0。
在 Spark 4.1 中,PySpark 对 Pandas 的最低支持版本从 2.0.0 提高到了 2.2.0。
在 Spark 4.1 中,Spark Connect Python 客户端上的
DataFrame['name']不再立即验证列名。若要恢复旧行为,请将PYSPARK_VALIDATE_COLUMN_NAME_LEGACY环境变量设置为1。在 Spark 4.1 中,Arrow 优化的 Python UDF 支持 UDT 输入/输出,不再回退到常规 UDF。若要恢复旧行为,请将
spark.sql.execution.pythonUDF.arrow.legacy.fallbackOnUDT设置为true。在 Spark 4.1 中,当启用了
spark.sql.execution.pythonUDF.arrow.enabled时,移除了不必要的向 pandas 实例的转换。因此,当产生的输出模式与指定模式不同时,类型强制转换会发生变化。若要恢复之前的行为,请启用spark.sql.legacy.execution.pythonUDF.pandas.conversion.enabled。在 Spark 4.1 中,当启用了
spark.sql.execution.pythonUDTF.arrow.enabled时,移除了不必要的向 pandas 实例的转换。因此,当产生的输出模式与指定模式不同时,类型强制转换会发生变化。若要恢复之前的行为,请启用spark.sql.legacy.execution.pythonUDTF.pandas.conversion.enabled。在 Spark 4.1 中,
BinaryType数据类型在 PySpark 中默认统一映射为 Python 的bytes类型。若要恢复之前的行为,请将spark.sql.execution.pyspark.binaryAsBytes设置为false。Spark 4.1.0 之前的行为如下表所示:情况
BinaryType的 Python 类型无 Arrow 优化的常规 UDF 和 UDTF
bytearrayDataFrame API(Spark Classic 和 Spark Connect)
bytearray数据源
bytearray带有不必要转换至 pandas 实例的 Arrow 优化 UDF 和 UDTF
bytes在 Spark 4.1 中,默认启用了
spark.sql.execution.pandas.convertToArrowArraySafely配置。启用此设置后,PyArrow 会针对不安全的转换(如整数溢出、浮点数截断和精度损失)抛出错误。此更改会影响启用了 Arrow 的 UDF/pandas_udfs 的返回数据序列化,以及 PySpark DataFrame 的创建。若要恢复之前的行为,请将该配置设置为false。在 Spark 4.1 中,当
compute.ansi_mode_support设置为True(默认)时,Spark 上的 pandas API 在 ANSI 模式下工作。安全保护选项compute.fail_on_ansi_mode仍然可用,但仅在compute.ansi_mode_support为False时生效。
从 PySpark 3.5 升级到 4.0#
在 Spark 4.0 中,PySpark 停止了对 Python 3.8 的支持。
在 Spark 4.0 中,PySpark 对 Pandas 的最低支持版本从 1.0.5 提高到了 2.0.0。
在 Spark 4.0 中,PySpark 对 Numpy 的最低支持版本从 1.15 提高到了 1.21。
在 Spark 4.0 中,PySpark 对 PyArrow 的最低支持版本从 4.0.0 提高到了 11.0.0。
在 Spark 4.0 中,Spark 上的 pandas API 移除了
Int64Index和Float64Index,应直接使用Index。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.iteritems,请改用DataFrame.items。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Series.iteritems,请改用Series.items。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.append,请改用ps.concat。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Series.append,请改用ps.concat。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.mad。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Series.mad。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Index.factorize和Series.factorize中的na_sentinel参数,请改用use_na_sentinel。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Categorical.add_categories、Categorical.remove_categories等方法中的inplace参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
CategoricalIndex.add_categories等方法中的inplace参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
ps.date_range中的closed参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.between_time中的include_start和include_end参数,请改用inclusive。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Series.between_time中的include_start和include_end参数,请改用inclusive。在 Spark 4.0 中,Spark 上的 pandas API 中
DatetimeIndex的各种日期时间属性(day,month,year等)现在为int32而不是int64。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.plot和Series.plot中的sort_columns参数。在 Spark 4.0 中,Spark 上的 pandas API 中
Series.str.replace的regex参数默认值从True改为False。此外,当regex=True时,单字符pat现在被视为正则表达式,而不是字符串字面量。在 Spark 4.0 中,Spark 上的 pandas API 中所有对象的
value_counts结果名称设置为'count'(如果传入normalize=True,则为'proportion'),索引将以原始对象命名。在 Spark 4.0 中,Spark 上的 pandas API 移除了
ps.read_csv和ps.read_excel中的squeeze参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.info中的null_counts参数,请改用show_counts。在 Spark 4.0 中,Spark 上的 pandas API 中
MultiIndex.append的结果不再保留索引名称。在 Spark 4.0 中,Spark 上的 pandas API 中列表相关的
DataFrameGroupBy.agg遵循as_index=False。在 Spark 4.0 中,Spark 上的 pandas API 中
DataFrame.stack保证了现有列的顺序,而不是按字典顺序排序。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Series.between的inclusive参数中的True或False,请分别改用both或neither。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Index.asi8,请改用Index.astype。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Index.is_type_compatible,请改用Index.isin。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.to_latex和Series.to_latex中的col_space参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.to_spark_io,请改用DataFrame.spark.to_spark_io。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Series.is_monotonic和Index.is_monotonic,请分别改用Series.is_monotonic_increasing或Index.is_monotonic_increasing。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.get_dtype_counts,请改用DataFrame.dtypes.value_counts()。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.to_excel和Series.to_excel中的encoding参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.to_excel和Series.to_excel中的verbose参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
read_csv中的mangle_dupe_cols参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrameGroupBy.backfill,请改用DataFrameGroupBy.bfill。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrameGroupBy.pad,请改用DataFrameGroupBy.ffill。在 Spark 4.0 中,Spark 上的 pandas API 移除了
Index.is_all_dates。在 Spark 4.0 中,Spark 上的 pandas API 移除了
read_excel中的convert_float参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
read_excel中的mangle_dupe_cols参数。在 Spark 4.0 中,Spark 上的 pandas API 移除了
DataFrame.koalas,请改用DataFrame.pandas_on_spark。在 Spark 4.0 中,PySpark 移除了
DataFrame.to_koalas,请改用DataFrame.pandas_api。在 Spark 4.0 中,PySpark 移除了
DataFrame.to_pandas_on_spark,请改用DataFrame.pandas_api。在 Spark 4.0 中,Spark 上的 Pandas API 移除了
DatatimeIndex.week和DatatimeIndex.weekofyear,请改用DatetimeIndex.isocalendar().week。在 Spark 4.0 中,Spark 上的 Pandas API 移除了
Series.dt.week和Series.dt.weekofyear,请改用Series.dt.isocalendar().week。在 Spark 4.0 中,当对十进制类型对象应用
astype时,Spark 上的 Pandas API 中现有的缺失值更改为True而非False。在 Spark 4.0 中,Spark 上的 Pandas API 移除了
pyspark.testing.assertPandasOnSparkEqual,请改用pyspark.pandas.testing.assert_frame_equal。在 Spark 4.0 中,Spark 上的 Pandas API 弃用了别名
Y,M,H,T,S,请分别改用YE,ME,h,min,s。在 Spark 4.0 中,Map 列的模式通过合并 Map 中所有对的模式来推断。若要恢复仅从第一个非空对推断模式的旧行为,可以将
spark.sql.pyspark.legacy.inferMapTypeFromFirstPair.enabled设置为true。在 Spark 4.0 中,
compute.ops_on_diff_frames默认开启。若要恢复之前的行为,请将compute.ops_on_diff_frames设置为false。在 Spark 4.0 中,
DataFrame.collect中的YearMonthIntervalType数据类型不再返回底层整数。若要恢复之前的行为,请将PYSPARK_YM_INTERVAL_LEGACY环境变量设置为1。在 Spark 4.0 中,函数以外的项目(如
DataFrame,Column,StructType)已从通配符导入from pyspark.sql.functions import *中移除,您应该从相应的模块中导入这些项目(例如from pyspark.sql import DataFrame, Column,from pyspark.sql.types import StructType)。在 Spark 4.0 中,如果底层的 Spark 启用了 ANSI 模式(默认启用),Spark 上的 pandas API 将抛出异常,因为它无法在 ANSI 模式下正常工作。要使其工作,您需要通过将
spark.sql.ansi.enabled设置为false来显式禁用 ANSI 模式。或者,您可以将 pandas-on-spark 选项compute.fail_on_ansi_mode设置为False以强制其工作,尽管这可能会导致意外行为。
从 PySpark 3.3 升级到 3.4#
在 Spark 3.4 中,Array 列的模式通过合并数组中所有元素的模式来推断。若要恢复仅从第一个元素推断模式的旧行为,可以将
spark.sql.pyspark.legacy.inferArrayTypeFromFirstElement.enabled设置为true。在 Spark 3.4 中,如果 Pandas on Spark API
Groupby.apply的func参数返回类型未指定且compute.shortcut_limit设置为 0,采样行数将设置为 2(确保采样行数始终 >= 2),以确保模式推断准确。在 Spark 3.4 中,如果 Pandas on Spark API
Index.insert越界,将引发IndexError,提示index {} is out of bounds for axis 0 with size {},以遵循 pandas 1.4 的行为。在 Spark 3.4 中,Pandas on Spark API
Series.mode将保留 Series 名称,以遵循 pandas 1.4 的行为。在 Spark 3.4 中,Pandas on Spark API
Index.__setitem__将首先检查value类型是否为Column类型,以避免在is_list_like中引发意外的ValueError。在 Spark 3.4 中,Pandas on Spark API
astype('category')也会根据原始数据dtype刷新categories.dtype,以遵循 pandas 1.4 的行为。在 Spark 3.4 中,Pandas on Spark API 在
GroupBy.head和GroupBy.tail中支持分组位置索引,以遵循 pandas 1.4 的行为。负数参数现在可以正确工作,并产生相对于每个组末尾和开头的范围。以前,负数参数会返回空帧。在 Spark 3.4 中,Pandas on Spark 中
groupby.apply的推断模式过程将首先推断 pandas 类型,以尽可能确保 pandasdtype的准确性。在 Spark 3.4 中,
Series.concat的 sort 参数将被尊重,以遵循 pandas 1.4 的行为。在 Spark 3.4 中,
DataFrame.__setitem__将进行复制并替换预先存在的数组,这些数组将不会被覆盖,以遵循 pandas 1.4 的行为。在 Spark 3.4 中,
SparkSession.sql和 Pandas on Spark APIsql获得了新参数args,该参数提供命名参数与其 SQL 字面量的绑定。在 Spark 3.4 中,Pandas API on Spark 遵循 pandas 2.0,并且根据 pandas 2.0 中的更改,一些 API 在 Spark 3.4 中已被弃用或移除。详情请参考 [pandas 发布说明](https://pandas.ac.cn/docs/dev/whatsnew/)。
在 Spark 3.4 中,移除了
collections.namedtuple的自定义猴子补丁,并默认使用cloudpickle。若要恢复任何相关collections.namedtuple序列化问题的先前行为,请将PYSPARK_ENABLE_NAMEDTUPLE_PATCH环境变量设置为1。
从 PySpark 3.2 升级到 3.3#
在 Spark 3.3 中,
pyspark.pandas.sql方法遵循 [标准 Python 字符串格式化程序](https://docs.pythonlang.cn/3/library/string.html#format-string-syntax)。若要恢复之前的行为,请将PYSPARK_PANDAS_SQL_LEGACY环境变量设置为1。在 Spark 3.3 中,Spark DataFrame 上 pandas API 的
drop方法支持按index删除行,并默认设置为按索引删除而不是按列删除。在 Spark 3.3 中,PySpark 升级了 Pandas 版本,新的最低要求版本从 0.23.2 变为 1.0.5。
在 Spark 3.3 中,SQL DataTypes 的
repr返回值已更改,以便在传递给eval时产生具有相同值的对象。
从 PySpark 3.1 升级到 3.2#
在 Spark 3.2 中,来自 sql, ml, spark_on_pandas 模块的 PySpark 方法在应用于不适当类型的参数时会引发
TypeError而不是ValueError。在 Spark 3.2 中,默认简化了 Python UDF、pandas UDF 和 pandas 函数 API 的回溯信息,不再包含来自内部 Python 工作线程的回溯。在 Spark 3.1 或更早版本中,会打印来自 Python 工作线程的回溯。若要恢复 Spark 3.2 之前的行为,可以将
spark.sql.execution.pyspark.udf.simplifiedTraceback.enabled设置为false。在 Spark 3.2 中,默认启用了固定线程模式,将每个 Python 线程映射到相应的 JVM 线程。以前,一个 JVM 线程可以被多个 Python 线程重用,导致一个 JVM 线程本地变量被多个 Python 线程共享。此外,请注意现在建议对 Python 线程使用
pyspark.InheritableThread或pyspark.inheritable_thread_target,以便 Python 线程正确继承 JVM 线程中的可继承属性(如局部属性),并避免潜在的资源泄漏问题。若要恢复 Spark 3.2 之前的行为,可以将PYSPARK_PIN_THREAD环境变量设置为false。
从 PySpark 2.4 升级到 3.0#
在 Spark 3.0 中,PySpark 要求 pandas 版本为 0.23.2 或更高版本,才能使用与 pandas 相关的功能,例如
toPandas、从 pandas DataFrame 创建createDataFrame等。在 Spark 3.0 中,PySpark 要求 PyArrow 版本为 0.12.1 或更高版本,才能使用与 PyArrow 相关的功能,例如
pandas_udf、toPandas以及设置了 “spark.sql.execution.arrow.enabled=true” 的createDataFrame等。在 PySpark 中,使用
SparkSession.builder.getOrCreate()创建SparkSession时,如果已经存在SparkContext,构建器以前会尝试用指定给构建器的配置来更新现有SparkContext的SparkConf。但由于SparkContext是由所有SparkSession共享的,我们不应该更新它们。在 3.0 中,构建器不再更新配置。这与 2.3 及更高版本中的 Java/Scala API 行为相同。如果您想更新它们,需要在创建SparkSession之前进行更新。在 PySpark 中,当启用了 Arrow 优化时,如果 Arrow 版本高于 0.11.0,Arrow 可以在序列化期间将 pandas.Series 转换为 Arrow 数组时执行安全类型转换。当检测到不安全类型转换(如溢出)时,Arrow 会引发错误。您可以通过设置
spark.sql.execution.pandas.convertToArrowArraySafely为 true 来启用它。默认设置为 false。PySpark 对 Arrow 版本的行为如下图所示:PyArrow 版本
整数溢出
浮点数截断
0.11.0 及以下
引发错误
静默允许
> 0.11.0, arrowSafeTypeConversion=false
静默溢出
静默允许
> 0.11.0, arrowSafeTypeConversion=true
引发错误
引发错误
在 Spark 3.0 中,PySpark 中的
createDataFrame(..., verifySchema=True)也会验证 LongType。以前,LongType 未被验证,在值溢出的情况下导致返回 None。若要恢复此行为,可以将 verifySchema 设置为 False 以禁用验证。从 Spark 3.0 开始,对于 Python 3.6 及以上版本,使用命名参数构造
Row时,字段名不再按字母顺序排序,字段顺序将与输入顺序一致。要像 Spark 2.4 那样默认启用字段排序,请为执行器和驱动程序设置环境变量PYSPARK_ROW_FIELD_SORTING_ENABLED为 true - 此环境变量必须在所有执行器和驱动程序上保持一致;否则,可能会导致失败或错误的结果。对于低于 3.6 的 Python 版本,字段名将始终按字母顺序排序。在 Spark 3.0 中,
pyspark.ml.param.shared.Has*混合类不再提供任何set*(self, value)设置器方法,请改用相应的self.set(self.*, value)。详情请参阅 SPARK-29093。
从 PySpark 2.3 升级到 2.4#
在 PySpark 中,当启用 Arrow 优化时,以前
toPandas在无法使用 Arrow 优化时会失败,而从 Pandas DataFrame 创建的createDataFrame允许回退到非优化方式。现在,toPandas和从 Pandas DataFrame 创建的createDataFrame默认都允许回退,这可以通过spark.sql.execution.arrow.fallback.enabled进行切换。
从 PySpark 2.3.0 升级到 2.3.1 及以上#
从 2.3.1 版本开始,包括
pandas_udf以及设置了spark.sql.execution.arrow.enabled为True的toPandas()/createDataFrame()在内的 Arrow 功能已被标记为实验性。这些功能仍在不断演进,目前不建议在生产环境中使用。
从 PySpark 2.2 升级到 2.3#
在 PySpark 中,现在如果您想使用与 Pandas 相关的功能(如
toPandas、从 Pandas DataFrame 创建createDataFrame等),则需要 Pandas 0.19.2 或更高版本。在 PySpark 中,与 Pandas 相关功能的时间戳值行为已更改,以尊重会话时区。如果您想使用旧行为,需要将配置
spark.sql.execution.pandas.respectSessionTimeZone设置为 False。详情请参阅 SPARK-22395。在 PySpark 中,
na.fill()或fillna现在也接受布尔值,并将空值替换为布尔值。在之前的 Spark 版本中,PySpark 会忽略它并返回原始的 Dataset/DataFrame。在 PySpark 中,当
to_replace不是字典时,df.replace不允许省略值。以前,在其他情况下可以省略值并默认为 None,这违反直觉且容易出错。
从 PySpark 1.4 升级到 1.5#
Python 中字符串到列的解析现在支持使用点 (.) 来限定列或访问嵌套值。例如
df['table.column.nestedField']。但是,这意味着如果您的列名包含任何点,则必须现在使用反引号转义它们(例如table.`column.with.dots`.nested)。PySpark 中的 DataFrame.withColumn 方法支持添加新列或替换同名的现有列。
从 PySpark 1.0-1.2 升级到 1.3#
在 Python 中使用 DataTypes 时,您需要构造它们(即
StringType()),而不是引用单例。