【问题标题】:apply function to all values in array column pyspark将函数应用于数组列 pyspark 中的所有值
【发布时间】:2020-02-18 14:38:20
【问题描述】:

我想让我的 pyspark 数据框中的数组列中的所有值都为负而不爆炸(!)。我试过这个 udf 但它没有用:

negative = func.udf(lambda x: x * -1, T.ArrayType(T.FloatType()))
cast_contracts = cast_contracts \
    .withColumn('forecast_values', negative('forecast_values'))

有人可以帮忙吗?

示例数据框:

df = sc..parallelize(
   [Row(name='Joe', forecast_values=[1.0,2.0,3.0]),
    Row(name='Mary', forecast_values=[4.0,7.1])]).toDF()
>>> df.show()
    +----+---------------+
    |name|forecast_values|
    +----+---------------+
    | Joe|[1.0, 2.0, 3.0]|
    |Mary|     [4.0, 7.1]|
    +----+---------------+

谢谢

【问题讨论】:

  • negative = func.udf(lambda x: [i * -1 for i in x], T.ArrayType(T.FloatType()))??

标签: arrays apache-spark pyspark user-defined-functions


【解决方案1】:

只是您没有循环遍历列表值以将它们与 -1 相乘

import pyspark.sql.functions as F
import pyspark.sql.types as T

negative = F.udf(lambda x: [i * -1 for i in x], T.ArrayType(T.FloatType()))
cast_contracts = df \
    .withColumn('forecast_values', negative('forecast_values'))

您无法逃避udf,但这是最好的方法。如果您的列表很大,效果会更好:

import numpy as np

negative = F.udf(lambda x: np.negative(x).tolist(), T.ArrayType(T.FloatType()))
cast_contracts = abdf \
    .withColumn('forecast_values', negative('forecast_values'))
cast_contracts.show()
+------------------+----+
|   forecast_values|name|
+------------------+----+
|[-1.0, -2.0, -3.0]| Joe|
|            [-3.0]|Mary|
|      [-4.0, -7.1]|Mary|
+------------------+----+

【讨论】:

  • 谢谢。这将返回一个空数组。也许我的数组是一个字符串数组,我需要先将它转换为浮点数。此外,我的运行时间似乎增加了 12 分钟。你认为这可能只是由于 udf 造成的吗?
  • @LN_P 是的,UDF 会破坏您的性能,但没有内置功能可对 array 类型的列进行操作。您正在处理多少行?
  • negative = F.udf(lambda x: [float(i) * -1 for i in x], T.ArrayType(T.FloatType())) 如果是字符串
【解决方案2】:

我知道这是一年前的帖子,因此我将要提供的解决方案可能以前不是一个选项(它是 Spark 3 的新功能)。如果您在 PySpark API 中使用 spark 3.0 及更高版本,则应考虑在 pyspark.sql.functions.expr 中使用 spark.sql.function.transform。 请不要将 spark.sql.function.transform 与 PySpark 的 transform() 链接混淆。无论如何,这是解决方案:

df.withColumn("negative", F.expr("transform(forecast_values, x -> x * -1)"))

您只需确保将值转换为 int 或 float。强调的方法比爆炸数组或使用 UDF 更有效。

【讨论】:

  • 从 2.4 开始提供
猜你喜欢
  • 2017-03-16
  • 2019-11-19
  • 1970-01-01
  • 1970-01-01
  • 2016-08-19
  • 2019-06-18
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
相关资源
最近更新 更多