升级 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 已移除
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
、Categorical.set_categories
、Categorical.rename_categories
、Categorical.reorder_categories
、Categorical.as_ordered
和Categorical.as_unordered
的inplace
参数。在 Spark 4.0 中,Spark 上的 pandas API 已移除
CategoricalIndex.add_categories
、CategoricalIndex.remove_categories
、CategoricalIndex.remove_unused_categories
、CategoricalIndex.set_categories
、CategoricalIndex.rename_categories
、CategoricalIndex.reorder_categories
、CategoricalIndex.as_ordered
和CategoricalIndex.as_unordered
的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 列的 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 中,除函数外的项(例如
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 中,数组列的 schema 是通过合并数组中所有元素的 schema 来推断的。要恢复之前仅从第一个元素推断 schema 的行为,可以将
spark.sql.pyspark.legacy.inferArrayTypeFromFirstElement.enabled
设置为true
。在 Spark 3.4 中,如果 Spark API 上的 Pandas
Groupby.apply
的func
参数返回类型未指定且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.head
和GroupBy.tail
中的 groupby 位置索引,以遵循 pandas 1.4。负参数现在可以正常工作,并生成相对于每个组的末尾和开头的范围,以前负参数返回空帧。在 Spark 3.4 中,Spark 上的 Pandas 中
groupby.apply
的 schema 推断过程将首先推断 pandas 类型,以尽可能确保 pandasdtype
的准确性。在 Spark 3.4 中,
Series.concat
的排序参数将遵循 pandas 1.4 的行为。在 Spark 3.4 中,
DataFrame.__setitem__
将创建副本并替换预先存在的数组,这些数组将不会被覆盖,以遵循 pandas 1.4 的行为。在 Spark 3.4 中,
SparkSession.sql
和 Spark API 上的 Pandassql
增加了新参数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.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,用于执行器和驱动程序——此环境变量必须在所有执行器和驱动程序上保持一致;否则,可能会导致故障或不正确的答案。对于 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
设置为True
的toPandas()
/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()
),而不是引用单例。