在map函数使用的UDF中返回所有列+更多列

时间:2016-09-29 15:17:48

标签: apache-spark pyspark spark-dataframe

我使用map函数生成一个新列,其值取决于数据帧中已存在的列的结果。

def computeTechFields(row):
    if row.col1!=VALUE_TO_COMPARE:
            tech1=0
    else:
            tech1=1
    return (row.col1, row.col2, row.col3, tech1)

delta2rdd = delta.map(computeTechFields)

问题是我的主数据框有超过150列,我必须使用map函数返回,所以最后我有这样的事情:

return (row.col1, row.col2, row.col3, row.col4, row.col5, row.col6, row.col7, row.col8, row.col9, row.col10, row.col11, row.col12, row.col13, row.col14, row.col15, row.col16, row.col17, row.col18 ..... row.col149, row.col150, row.col151, tech1)

正如你所看到的,写作真的很长,难以阅读。所以我试着做这样的事情:

return (row.*, tech1)

但当然它不起作用。

我知道" withColumn"功能存在,但我对其性能了解不多,无论如何也无法使其发挥作用。

编辑(withColumn函数发生了什么):

def computeTech1(row):
    if row.col1!=VALUE_TO_COMPARE:
            tech1=0
    else:
            tech1=1
    return tech1

delta2 = delta.withColumn("tech1", computeTech1)

它给了我这个错误:

AssertionError: col should be Column

我试着这样做:

return col(tech1)

错误是相同的

我也尝试过:

delta2 = delta.withColumn("tech1", col(computeTech1))

这一次,错误是:

AttributeError: 'function' object has no attribute '_get_object_id'

编辑结束

所以我的问题是,如何在map函数使用的UDF中返回所有列+更多列?

谢谢!

1 个答案:

答案 0 :(得分:2)

使用Python并不是非常坚定,所以人们可能会在这里纠正我的语法,但一般的想法是让你的函数成为一个带有列作为输入的UDF,然后在withColumn内调用它。我在这里使用了一个lambda,但是有一些fiddeling它也可以使用一个函数。

from pyspark.sql.functions import udf

computeTech1UDF = udf(
   lambda col: 0 if col != VALUE_TO_COMPARE else 1, IntegerType())

delta2 = delta.withColumn("tech1", computeTech1UDF(col1))

由于您未向withColumn提供列表达式,因此您尝试的内容无效(请参阅http://spark.apache.org/docs/1.6.0/api/python/pyspark.sql.html#pyspark.sql.DataFrame.withColumn)。使用UDF包装器可以实现这一点。