如何在Pyspark中的dataframe withColumn函数中使用函数?

时间:2017-05-30 10:18:50

标签: function apache-spark dataframe replace pyspark

我有一些词典和一个定义的函数:

dict_TEMPERATURE = {(0, 70): 'Low', (70.01, 73.99): 'Normal-Low',(74, 76): 'Normal', (76.01, 80): 'Normal-High', (80.01, 300): 'High'}
...
hierarchy_dict = {'TEMP': dict_TEMPERATURE, 'PRESS': dict_PRESSURE, 'SH_SP': dict_SHAFT_SPEED, 'POI': dict_POI, 'TRIG': dict_TRIGGER}



def function_definition(valor, atributo):

    dict_atributo = hierarchy_dict[atributo]
    valor_generalizado = None

    if isinstance(valor, (int, long, float, complex)):

        for key, value in dict_atributo.items():

            if(isinstance(key, tuple)):
                lista = list(key)

                if (valor > key[0] and valor < key[1]):
                    valor_generalizado = value

    else: # if it is not numeric
        valor_generalizado = dict_atributo.get(valor)


    return valor_generalizado

这个函数基本上做的是:检查作为参数传递给&#34; function_definition&#34;的值。函数,并根据其字典的引用替换它的值。

所以,如果我打电话给&#34; function_definition(60,&#39; TEMP&#39;)&#34;它将返回&#39; LOW&#39;

另一方面,我有一个带有下一个结构的数据帧(这是一个例子):

+----+-----+-----+---+----+
|TEMP|SH_SP|PRESS|POI|TRIG|
+----+-----+-----+---+----+
|   0|    1|    2|  0|   0|
|   0|    2|    3|  1|   1|
|   0|    3|    4|  2|   1|
|   0|    4|    5|  3|   1|
|   0|    5|    6|  4|   1|
|   0|    1|    2|  5|   1|
+----+-----+-----+---+----+

我想要做的是根据上面定义的函数替换数据框的一列的值,所以我有下一个代码行:

dataframe_new = dataframe.withColumn(atribute_name, function_definition(dataframe[atribute_name], atribute_name))

但是在执行时我收到了下一条错误消息:

AssertionError: col should be Column

我的代码有什么问题?怎么可能呢?

1 个答案:

答案 0 :(得分:1)

function_definition(valor,atributo)为单个 valor 返回单个字符串( valor_generalizado )。

断言错误:col应为列表示您将参数传递给WithColumn(colName,col),而不是列。 因此,您必须转换数据,以便拥有 Column ,例如,如下所示。

Dataframe例如(与您的结构相同):

a = [(10.0,1.2),(73.0,4.0)] # like your dataframe, this is only an example

dataframe = spark.createDataFrame(a,["tp", "S"]) # tp and S are random names for these columns

dataframe.show()
+----+---+
|  tp|  S|
+----+---+
|10.0|1.2|
|73.0|4.0|
+----+---+

正如您所见here

  

udf 创建表示用户定义函数(UDF)的Column表达式。

解决方案:

from pyspark.sql.functions import udf

attr = 'TEMP'
udf_func = udf(lambda x: function_definition(x,attr),returnType=StringType())

dataframe_new = dataframe.withColumn("newCol",udf_func(dataframe.tp))
dataframe_new.show()

+----+---+----------+
|  tp|  S|    newCol|
+----+---+----------+
|10.0|1.2|       Low|
|73.0|4.0|Normal-Low|
+----+---+----------+