升级 PySpark#

从 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 已移除 Int64IndexFloat64Index,应直接使用 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.factorizeSeries.factorizena_sentinel 参数,请改用 use_na_sentinel

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 Categorical.add_categoriesCategorical.remove_categoriesCategorical.set_categoriesCategorical.rename_categoriesCategorical.reorder_categoriesCategorical.as_orderedCategorical.as_unorderedinplace 参数。

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 CategoricalIndex.add_categoriesCategoricalIndex.remove_categoriesCategoricalIndex.remove_unused_categoriesCategoricalIndex.set_categoriesCategoricalIndex.rename_categoriesCategoricalIndex.reorder_categoriesCategoricalIndex.as_orderedCategoricalIndex.as_unorderedinplace 参数。

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 ps.date_rangeclosed 参数。

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 DataFrame.between_timeinclude_startinclude_end 参数,请改用 inclusive

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 Series.between_timeinclude_startinclude_end 参数,请改用 inclusive

  • 在 Spark 4.0 中,Spark 上的 pandas API 中 DatetimeIndex 的各种日期时间属性(如 daymonthyear 等)现在是 int32 而不是 int64

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 DataFrame.plotSeries.plotsort_columns 参数。

  • 在 Spark 4.0 中,Spark 上的 pandas API 中 Series.str.replaceregex 参数的默认值已从 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_csvps.read_excelsqueeze 参数。

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 DataFrame.infonull_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.betweeninclusive 参数的 TrueFalse 值,请分别改用 bothneither

  • 在 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_latexSeries.to_latexcol_space 参数。

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 DataFrame.to_spark_io,请改用 DataFrame.spark.to_spark_io

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 Series.is_monotonicIndex.is_monotonic,请分别改用 Series.is_monotonic_increasingIndex.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_excelSeries.to_excelencoding 参数。

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 DataFrame.to_excelSeries.to_excelverbose 参数。

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 read_csvmangle_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_excelconvert_float 参数。

  • 在 Spark 4.0 中,Spark 上的 pandas API 已移除 read_excelmangle_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.weekDatatimeIndex.weekofyear,请改用 DatetimeIndex.isocalendar().week

  • 在 Spark 4.0 中,Spark 上的 Pandas API 已移除 Series.dt.weekSeries.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 已弃用别名 YMHTS,请分别改用 YEMEhmins

  • 在 Spark 4.0 中,map 列的 schema 是通过合并 map 中所有键值对的 schema 来推断的。要恢复之前仅从第一个非空键值对推断 schema 的行为,可以将 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 中,除函数外的项(例如 DataFrameColumnStructType)已从通配符导入 from pyspark.sql.functions import * 中移除,您应该从适当的模块导入这些项(例如 from pyspark.sql import DataFrame, Columnfrom 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 中,数组列的 schema 是通过合并数组中所有元素的 schema 来推断的。要恢复之前仅从第一个元素推断 schema 的行为,可以将 spark.sql.pyspark.legacy.inferArrayTypeFromFirstElement.enabled 设置为 true

  • 在 Spark 3.4 中,如果 Spark API 上的 Pandas Groupby.applyfunc 参数返回类型未指定且 compute.shortcut_limit 设置为 0,则采样行将设置为 2(确保采样行始终 >= 2),以确保推断的 schema 准确无误。

  • 在 Spark 3.4 中,如果 Spark API 上的 Pandas Index.insert 超出范围,将引发 IndexError,并显示 index {} is out of bounds for axis 0 with size {},以遵循 pandas 1.4 的行为。

  • 在 Spark 3.4 中,Spark API 上的 Pandas Series.mode 将保留序列名称,以遵循 pandas 1.4 的行为。

  • 在 Spark 3.4 中,Spark API 上的 Pandas Index.__setitem__ 将首先检查 value 类型是否为 Column 类型,以避免在 is_list_like 中引发意外的 ValueError,例如 无法将列转换为布尔值:构建 DataFrame 布尔表达式时,请使用 ‘&’ 表示 ‘and’,‘|’ 表示 ‘or’,‘~’ 表示 ‘not’。

  • 在 Spark 3.4 中,Spark API 上的 Pandas astype('category') 也将根据原始数据 dtype 刷新 categories.dtype,以遵循 pandas 1.4 的行为。

  • 在 Spark 3.4 中,Spark API 上的 Pandas 支持 GroupBy.headGroupBy.tail 中的 groupby 位置索引,以遵循 pandas 1.4。负参数现在可以正常工作,并生成相对于每个组的末尾和开头的范围,以前负参数返回空帧。

  • 在 Spark 3.4 中,Spark 上的 Pandas 中 groupby.apply 的 schema 推断过程将首先推断 pandas 类型,以尽可能确保 pandas dtype 的准确性。

  • 在 Spark 3.4 中,Series.concat 的排序参数将遵循 pandas 1.4 的行为。

  • 在 Spark 3.4 中,DataFrame.__setitem__ 将创建副本并替换预先存在的数组,这些数组将不会被覆盖,以遵循 pandas 1.4 的行为。

  • 在 Spark 3.4 中,SparkSession.sql 和 Spark API 上的 Pandas sql 增加了新参数 args,该参数提供了命名参数与其 SQL 字面量的绑定。

  • 在 Spark 3.4 中,Spark 上的 Pandas API 遵循 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 相关 pickle 问题的行为,请将 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 worker 的回溯。在 Spark 3.1 或更早版本中,会打印出 Python worker 的回溯。要恢复 Spark 3.2 之前的行为,您可以将 spark.sql.execution.pyspark.udf.simplifiedTraceback.enabled 设置为 false

  • 在 Spark 3.2 中,默认启用固定线程模式,将每个 Python 线程映射到相应的 JVM 线程。以前,一个 JVM 线程可以被多个 Python 线程重用,导致一个 JVM 线程局部变量被多个 Python 线程共享。此外,请注意,现在建议将 pyspark.InheritableThreadpyspark.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_udftoPandas 和使用“spark.sql.execution.arrow.enabled=true”的 createDataFrame 等。

  • 在 PySpark 中,当使用 SparkSession.builder.getOrCreate() 创建 SparkSession 时,如果存在现有的 SparkContext,构建器会尝试使用为构建器指定的配置来更新现有 SparkContextSparkConf,但 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,用于执行器和驱动程序——此环境变量必须在所有执行器和驱动程序上保持一致;否则,可能会导致故障或不正确的答案。对于 Python 3.6 以下的版本,字段名称将按字母顺序排序,这是唯一的选项。

  • 在 Spark 3.0 中,pyspark.ml.param.shared.Has* mixin 不再提供任何 set*(self, value) setter 方法,请改用相应的 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 版本起,Arrow 功能(包括 pandas_udf 和将 spark.sql.execution.arrow.enabled 设置为 TruetoPandas()/createDataFrame())已被标记为实验性。这些功能仍在发展中,目前不建议在生产环境中使用。

从 PySpark 2.2 升级到 2.3#

  • 在 PySpark 中,如果您想使用与 Pandas 相关的功能(例如 toPandas、从 Pandas DataFrame 创建 createDataFrame 等),现在需要 Pandas 0.19.2 或更高版本。

  • 在 PySpark 中,与 Pandas 相关功能的 timestamp 值行为已更改为尊重会话时区。如果您想使用旧行为,需要将配置 spark.sql.execution.pandas.respectSessionTimeZone 设置为 False。详情请参阅 SPARK-22395

  • 在 PySpark 中,na.fill()fillna 也接受布尔值并用布尔值替换空值。在之前的 Spark 版本中,PySpark 会忽略它并返回原始的 Dataset/DataFrame。

  • 在 PySpark 中,当 to_replace 不是字典时,df.replace 不允许省略 value。以前,在其他情况下可以省略 value,并且默认值为 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()),而不是引用单例。