我有一个数据框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]
我想创建一个新列,该列等于array
中值的元素除以distances
中相应值。我尝试了以下方法:
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).
但是,当我运行此代码时:
a = [115.63,115.01,114.14]
b= 115.63
print(np.divide([115.63,115.01,114.14], 115.63))
它有效,并给我以下结果:[ 1. 0.99463807 0.98711407]
。为什么在PySpark案例中它不起作用,如何修改我的代码使其起作用?
答案 0 :(得分:1)
它在外部起作用的原因是您正在使用本机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']))
另一方面,如果要归一化的总和,则可以使用explode
:
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)')