Pyspark 错误:TypeError:不能将类型 <type 'NoneType'> 视为向量 [重复]

Posted

技术标签:

【中文标题】Pyspark 错误:TypeError:不能将类型 <type \'NoneType\'> 视为向量 [重复]【英文标题】:Pyspark error: TypeError: Cannot treat type <type 'NoneType'> as a vector [duplicate]Pyspark 错误:TypeError:不能将类型 <type 'NoneType'> 视为向量 [重复] 【发布时间】:2018-07-31 13:23:49 【问题描述】:

我有以下代码:

from pyspark.sql.types import *
from pyspark.ml.linalg import Vectors, VectorUDT
import pyspark.sql.functions as F

dot_udf = F.udf(lambda x,y: float(x.dot(y)), DoubleType())
l = [(Vectors.dense([1, 2, 3, 4 ,5]), Vectors.dense([5, 4, 3, 2, 1]),),
     (Vectors.dense([0, 4, 8, 2, 1]), None,),
     (None, Vectors.dense([5, 0, 3, 9, 1]),),
     ]

def finish(row):
    new_row = []
    new_row.append(None if row['my_row_1'] == None else Vectors.dense(row['my_row_1']))
    new_row.append(None if row['my_row_2'] == None else Vectors.dense(row['my_row_2']))
    return new_row


with (SparkSession
      .builder
      .appName('test_mtassoni')
      .getOrCreate()) as spark:
    schema = StructType([StructField('my_row_1', VectorUDT(), True),
                         StructField('my_row_2', VectorUDT(), True)])

    df = spark.createDataFrame(l, schema)
    rdd = df.rdd
    rdd = rdd.map(finish)

    out_schema = StructType([StructField('my_row_1', VectorUDT(), True),
                             StructField('my_row_2', VectorUDT(), True)])
    fdf = spark.createDataFrame(rdd, schema=out_schema)

    fdf = fdf.withColumn('row_sim', F.when(((F.col('my_row_1').isNull()) |
                                            (F.col('my_row_2').isNull())),
                                       np.nan).otherwise(dot_udf(fdf.my_row_1, fdf.my_row_2))
                     )
    fdf.show()

在最后一个命令上出现以下 TypeError 失败:

TypeError: Cannot treat type <type 'NoneType'> as a vector

有人知道如何解决吗?非常感谢您提前。

【问题讨论】:

您确定不想从row['my_row_1'] 中过滤掉Nones 吗? finish 函数正在返回一个列表,其中可能包含 Nones。 我不想过滤掉Nones。这只是一个示例数据集,但实际上我有更多列,我不想仅仅因为在那里找到None 而从数据框中删除条目。 【参考方案1】:

您的方法的问题是您在otherwise 部分调用了udf 函数,但事实是每一行都被传递给udf 函数。所以问题在于您将 column-wise 函数 (when/otherwise) 与 row-wise 函数 (udf)

解决方案是将when/otherwise 部分移动到udf 函数中

def dotProduct(x, y):
    if(x == None or y == None):
        return np.nan
    else:
        return float(x.dot(y))

dot_udf = F.udf(lambda x,y: dotProduct(x, y), DoubleType())

然后调用udf函数独立

fdf = fdf.withColumn('row_sim', dot_udf(fdf.my_row_1, fdf.my_row_2))
fdf.show()

这应该会给你正确的结果而没有错误

+--------------------+--------------------+-------+
|            my_row_1|            my_row_2|row_sim|
+--------------------+--------------------+-------+
|[1.0,2.0,3.0,4.0,...|[5.0,4.0,3.0,2.0,...|   35.0|
|[0.0,4.0,8.0,2.0,...|                null|    NaN|
|                null|[5.0,0.0,3.0,9.0,...|    NaN|
+--------------------+--------------------+-------+

希望回答对你有帮助

【讨论】:

我不知道这个问题。非常感谢,您的解决方案完美解决了我的问题!

以上是关于Pyspark 错误:TypeError:不能将类型 <type 'NoneType'> 视为向量 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

PySpark:TypeError:StructType 不能接受类型为 <type 'unicode'> 或 <type 'str'> 的对象

从 RDD 创建 df 时出现 pyspark 错误:TypeError:无法推断类型的架构:<type 'float'>

# 字符串方法 TypeError: 列在 pyspark 中不可迭代

为啥使用默认的 React Google Maps 得到“TypeError:无法将类调用为函数”?

Pyspark 和错误“TypeError:必须是实数,而不是 Column”,当尝试在窗口上使用定义的函数查找指南针方位时

pyspark:TypeError:'float'对象不可迭代