Pandas 使用ArrayType列将UDF重写为UDF

Pandas 使用ArrayType列将UDF重写为UDF,pandas,apache-spark,pyspark,user-defined-functions,Pandas,Apache Spark,Pyspark,User Defined Functions,我正在尝试将UDF重写为熊猫UDF 但是,当涉及到包含ArrayType的列时。我正在努力寻找正确的解决办法 我有一个数据帧,如下所示: +-----------+--------------------+ | genre| ids| +-----------+--------------------+ | Crime|[6, 22, 42, 47, 5...| | Romance|[3, 7, 11, 15, 17...| | Th

我正在尝试将UDF重写为熊猫UDF

但是,当涉及到包含ArrayType的列时。我正在努力寻找正确的解决办法

我有一个数据帧,如下所示:

+-----------+--------------------+
|      genre|                 ids|
+-----------+--------------------+
|      Crime|[6, 22, 42, 47, 5...|
|    Romance|[3, 7, 11, 15, 17...|
|   Thriller|[6, 10, 16, 18, 2...|
|  Adventure|[2, 8, 10, 15, 29...|
|   Children|[1, 2, 8, 13, 34,...|
|      Drama|[4, 11, 14, 16, 1...|
|        War|[41, 110, 151, 15...|
|Documentary|[37, 77, 99, 108,...|
|    Fantasy|[2, 56, 60, 126, ...|
|    Mystery|[59, 113, 123, 16...|
+-----------+--------------------+
以下UDF运行良好:

pairs_udf = udf(lambda x: itertools.combinations(x, 2), transformer.schema)
df = df.select("genre", pairs_udf("ids").alias("ids"))
输出如下所示:

+-----------+--------------------+
|      genre|                 ids|
+-----------+--------------------+
|      Crime|[[6, 22], [6, 42]...|
|    Romance|[[3, 7], [3, 11],...|
|   Thriller|[[6, 10], [6, 16]...|
|  Adventure|[[2, 8], [2, 10],...|
|   Children|[[1, 2], [1, 8], ...|
|      Drama|[[4, 11], [4, 14]...|
|        War|[[41, 110], [41, ...|
|Documentary|[[37, 77], [37, 9...|
|    Fantasy|[[2, 56], [2, 60]...|
|    Mystery|[[59, 113], [59, ...|
+-----------+--------------------+
但是,在
pandas udf
中编写函数时,什么是等效的

PS:我理解,或者,我可以使用交叉连接来实现相同的结果


但是,我更好奇的是pandas udf如何处理ArrayType列。

我将在这里分享我的发现:

要使熊猫udf在您的项目中发挥作用,有三个方面:

1.使用UDF,或者更准确地说,Apache Arrow不支持普通UDF所支持的复杂类型。(从
pyspark 3.0.1
pyarrow 2.0.0
) e、 g:

  • udf支持
    ArrayType(StringType())
  • 不支持数组类型(StructType([…])。 您可以查看更多:
2.如果您运行的是Java 11,这是(py)Spark 3中的默认值。您需要在spark配置中添加以下内容: 这将解决上面提到的
java.lang.UnsupportedOperationException

3.确保将虚拟环境python路径添加到
pyspark\u python
i、 e。
environ['PYSPARK\u PYTHON']='./your/virtual/environment/path'

可能类似于
lambda row:row.apply(lambda x:itertools.compositions(x,2))
谢谢,@mck,这是我的一次尝试。现在我认为我遇到的问题与
java.lang.UnsupportedOperationException有关:sun.misc.Unsafe或java.nio.DirectByteBuffer.(long,int)不可用
。经过几次谷歌搜索后,它似乎与Java11和SparkArrow支持有关。这可能属于一个单独的问题。
spark.driver.extraJavaOptions='-Dio.netty.tryReflectionSetAccessible=true'
spark.executor.extraJavaOptions='-Dio.netty.tryReflectionSetAccessible=true'