首页 > 解决方案 > pyspark ImageSchema.toNDArray 引发 AttributeError:“NoneType”对象没有属性“_jvm”

问题描述

pyspark.ml.image我在使用Spark 2.3的新功能时遇到问题。

ImageSchema.toNDArray()在“本地计算”中使用时,可以。但是在 中使用rdd.map()它会引发错误,

AttributeError:“NoneType”对象没有属性“_jvm”。

您可以在 pyspark 中尝试以下代码,并在“jpg”文件夹中准备好图片。比如我把这张单张图放进去。

在“本地计算”中可以:

>>> from pyspark.ml.image import ImageSchema
>>> df = ImageSchema.readImages("jpg")
>>> row = df.collect()[0]               # collect() to a "local" list and take the first
>>> ImageSchema.toNDArray(row.image)    # so this toNDArray() is a "local computation"
array([[[228, 141,  97],
        [229, 142,  98],
        [229, 142,  98],
        ...,
        [239, 157, 110],
        [239, 157, 110],
        [239, 157, 109]],
        ...    
        ...
       [[ 66,  38,  21],
        [ 66,  38,  21],
        [ 66,  38,  21],
        ...,
        [ 91,  55,  37],
        [ 94,  57,  37],
        [ 94,  57,  37]]], dtype=uint8)

但是如果我把它放在一个中rdd.map(),它会引发一个

AttributeError:“NoneType”对象没有属性“_jvm”

>>> from pyspark.ml.image import ImageSchema
>>> df = ImageSchema.readImages("jpg")
>>> df.rdd.map(lambda row: ImageSchema.toNDArray(row.image)).take(1)

...
...

  File "/opt/cloudera/parcels/SPARK2-2.3.0.cloudera2-1.cdh5.13.3.p0.316101/lib/spark2/python/lib/pyspark.zip/pyspark/ml/image.py", line 123, in toNDArray
    if any(not hasattr(image, f) for f in self.imageFields):
  File "/opt/cloudera/parcels/SPARK2-2.3.0.cloudera2-1.cdh5.13.3.p0.316101/lib/spark2/python/lib/pyspark.zip/pyspark/ml/image.py", line 90, in imageFields
    if self._imageFields is None:
        ctx = SparkContext._active_spark_context
        self._imageFields = list(ctx._jvm.org.apache.spark.ml.image.ImageSchema.imageFields())
AttributeError: 'NoneType' object has no attribute '_jvm'

        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.handlePythonException(PythonRunner.scala:298)
        at org.apache.spark.api.python.PythonRunner$$anon$1.read(PythonRunner.scala:438)
        at org.apache.spark.api.python.PythonRunner$$anon$1.read(PythonRunner.scala:421)
        at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.hasNext(PythonRunner.scala:252)
        at org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala:37)
        at scala.collection.Iterator$class.foreach(Iterator.scala:893)
        at org.apache.spark.InterruptibleIterator.foreach(InterruptibleIterator.scala:28)
        ...
        ...

这种情况已经过测试并且可以重现

Spark 2.3.0 provided by Cloudera parcel
Spark 2.3.0 on Hortonworks
Spark 2.3.0 on Windows with WinUtils
Spark 2.3.1 on Windows with WinUtils

什么问题?

我该如何解决?

标签: pysparkapache-spark-mllib

解决方案


我认为这是一个错误,因为如果我像下面这样pyspark.ml.image修改所有行.../lib/spark2/python/pyspark/ml/image.py

ctx = SparkContext._active_spark_context

进入

ctx = SparkContext.getOrCreate()

然后一切都会好起来的。

但是,我不是 pyspark 方面的专家。我想在我选择答案之前,我最好把它留给讨论。

PS我并不是说应该以这种方式纠正。我只是认为这可能是一个错误。


推荐阅读