【问题标题】:withColumn with UDF yields AttributeError: 'NoneType' object has no attribute '_jvm'带有 UDF 的 withColumn 产生 AttributeError:“NoneType”对象没有属性“_jvm”
【发布时间】:2017-11-29 11:57:52
【问题描述】:

我正在尝试使用 UDF 替换 spark 数据帧中的一些值,但仍然出现相同的错误。

在调试时我发现它并不依赖于我使用的数据框,也不依赖于我编写的函数。这是一个 MWE,它具有一个我无法正确执行的简单 lambda 函数。这基本上应该通过将值与自身连接来修改第一列中的所有值。

l = [('Alice', 1)]
df = sqlContext.createDataFrame(l)
df.show()

#+-----+---+
#|   _1| _2|
#+-----+---+
#|Alice|  1|
#+-----+---+

df = df.withColumn("_1", udf(lambda x : lit(x+x), StringType())(df["_1"]))
df.show()
#Alice should now become AliceAlice

这是我得到的错误,提到了一个相当神秘的“AttributeError:'NoneType'对象没有属性'_jvm”。

 File "/cdh/opt/cloudera/parcels/CDH-5.11.1-1.cdh5.11.1.p0.4/lib/spark/python/pyspark/worker.py", line 111, in main
    process()
  File "/cdh/opt/cloudera/parcels/CDH-5.11.1-1.cdh5.11.1.p0.4/lib/spark/python/pyspark/worker.py", line 106, in process
    serializer.dump_stream(func(split_index, iterator), outfile)
  File "/cdh/opt/cloudera/parcels/CDH-5.11.1-1.cdh5.11.1.p0.4/lib/spark/python/pyspark/serializers.py", line 263, in dump_stream
    vs = list(itertools.islice(iterator, batch))
  File "/cdh/opt/cloudera/parcels/CDH-5.11.1-1.cdh5.11.1.p0.4/lib/spark/python/pyspark/sql/functions.py", line 1566, in <lambda>
    func = lambda _, it: map(lambda x: returnType.toInternal(f(*x)), it)
  File "<stdin>", line 1, in <lambda>
  File "/cdh/opt/cloudera/parcels/CDH-5.11.1-1.cdh5.11.1.p0.4/lib/spark/python/pyspark/sql/functions.py", line 39, in _
    jc = getattr(sc._jvm.functions, name)(col._jc if isinstance(col, Column) else col)
AttributeError: 'NoneType' object has no attribute '_jvm'

我确信我对语法感到困惑并且无法正确输入类型(感谢鸭子打字!),但我发现的每个 withColumn 和 lambda 函数示例似乎都与这个相似。

【问题讨论】:

    标签: python dataframe lambda pyspark user-defined-functions


    【解决方案1】:

    您非常接近,这是在抱怨,因为您不能在 udf 中使用 lit :) lit 用于列级别,而不是行级别。

    l = [('Alice', 1)]
    df = spark.createDataFrame(l)
    df.show()
    
    +-----+---+
    |   _1| _2|
    +-----+---+
    |Alice|  1|
    +-----+---+
    
    df = df.withColumn("_1", udf(lambda x: x+x, StringType())("_1"))
    # this would produce the same result, but lit is not necessary here
    # df = df.withColumn("_1", udf(lambda x: x+x, StringType()(lit(df["_1"])))
    df.show()
    
    +----------+---+
    |        _1| _2|
    +----------+---+
    |AliceAlice|  1|
    +----------+---+
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    相关资源
    最近更新 更多