Python PySpark按浮点数划分数据帧数组

Python PySpark按浮点数划分数据帧数组,python,apache-spark,dataframe,pyspark,Python,Apache Spark,Dataframe,Pyspark,我有一个数据帧dfDistance。样本: DataIndex CenterIndex distances array 65 0 115.63 [115.63,115.01,114.14] 65 1 115.01 [115.63,115.01,114.14] 65 2 114.14 [115.63,

我有一个数据帧
dfDistance
。样本:

    DataIndex CenterIndex   distances           array
        65        0          115.63     [115.63,115.01,114.14]
        65        1          115.01     [115.63,115.01,114.14]
        65        2          114.14     [115.63,115.01,114.14]
我想创建一个新列,该列等于
数组中的值按元素除以
距离中的相应值。我尝试了以下方法:

temp = dfDistance.select("DataIndex",   "CenterIndex", "distances", (np.divide(dfDistance.array, dfDistance.distances)))
它给了我这个错误:

"cannot resolve '(`array` / `distances`)' due to data type mismatch: differing types in '(`array` / `distances`)' (array<float> and float).

它工作并给出了这个结果:
[1.0.99463807 0.98711407]
。为什么它在PySpark情况下不工作,我应该如何修改代码使其工作?

它在外部工作的原因是您使用的是本机Python类型(
list
float
)。另一方面,在PySpark中,您使用的是列对象,它们的行为方式不同

无论如何,我认为最简单的方法就是使用UDF。我试着浏览PySpark文档,但奇怪的是,找不到任何直接作用于数组的方法。例如:

from pyspark.sql import functions as F
from pyspark.sql.types import ArrayType, DoubleType

def normalise(a, dist):
    return [element / dist for element in a]

dfDistance.withColumn('normalised', F.udf(normalise, ArrayType(DoubleType()))(df['array'], df['distances']))
另一方面,如果需要归一化和,可以使用
分解

distance_sum = dfDistance.select('array', F.explode('array')).groupby('array').sum()

dfDistance.join(distance_sum, on='array', how='left').withColumn('normalised_sum', F.col('sum(col)') / F.col('distances')).drop('sum(col)')

你又救了我,谢谢你!正如您所看到的,我是Python/Spark新手,因此,请您解释一下,为什么在udf中编写ArrayType(DoubleType())?我不明白这个部分。@daibri
F.udf
接受两个参数:函数及其返回类型。默认情况下,所有UDF都返回字符串(
StringType
)。但是,我们需要一个双精度数组,所以我们需要指定
ArrayType(DoubleType)
。因此,如果我想返回sum作为结果而不是array,那么我应该有F.udf(normalise,DoubleType())(df['array'],df['distance'])?函数本身看起来像:返回和([element/dist for element in a])?@daibri-Yup,你可以这样做。不过,可能有一种更有效的基于
分解的方法。
distance_sum = dfDistance.select('array', F.explode('array')).groupby('array').sum()

dfDistance.join(distance_sum, on='array', how='left').withColumn('normalised_sum', F.col('sum(col)') / F.col('distances')).drop('sum(col)')