如何在Pyspark中将字符串转换为函数(动态函数)

时间:2019-06-12 14:08:11

标签: pyspark

我正在Pyspark中读取json文件并动态生成函数。

以下静态函数是在调用json文件(动态函数)之前创建的。

def rh_concatenate(*arg):
    return concat(*arg)

def rh_date_to_char(column_name, format1):
    if (format1 == 'MM'):
        return lpad(month(column_name).cast(StringType()), 2, '0')
    elif (format1 == 'YYYY'):
        return lpad(year(column_name).cast(StringType()), 4, '0')

JSON文件(Rule引擎)将返回字典“ exp_list”。

exp_list词典包含的键是“ QUARTER”,值是“ rh_concatenate('Q3','-',rh_date_to_char('TRANSACTION_DATE','YYYY'))'

方案1:无效

for key, value in exp_list.items():
    tran_df.withColumn(key, value).show()

方案2:工作正常。

tran_df.withColumn('QUARTER', rh_concatenate ('Q3','-',rh_date_to_char ('TRANSACTION_DATE','YYYY' ) )).show()

我已经尝试了多种方法来执行方案1并得到以下错误。

AssertionError: col should be Column

2 个答案:

答案 0 :(得分:0)

一切正常。

我添加了eval()函数,并且工作正常。

tran_df.withColumn(key, eval(value)).show()

如果value仅包含一个函数,则应添加col()函数,

tran_df.withColumn(key, col(value)).show()

示例

def rh_assign(arg):
    return arg

tran_df.withColumn('TRANSACTION_ID', col(rh_assign (('TRANSACTION_ID') ))).show()

答案 1 :(得分:0)

我的动态函数太大,并添加了评估函数,它运行良好。

请参阅下面的“我的键和值”。

item key : QUARTER
item value:  rh_if ((rh_less_than ((rh_str_to_num ((rh_date_to_char (('TRANSACTION_DATE'),('MM') )) )),('04') )),(rh_concatenate ((lit('Q1')),(lit('-')),(rh_date_to_char (('TRANSACTION_DATE'),('YYYY') )) )),(rh_if ((rh_less_than ((rh_str_to_num ((rh_date_to_char (('TRANSACTION_DATE'),('MM') )) )),(7) )),(rh_concatenate ((lit('Q2')),(lit('-')),(rh_date_to_char (('TRANSACTION_DATE'),('YYYY') )) )),(rh_if ((rh_less_than ((rh_str_to_num ((rh_date_to_char (('TRANSACTION_DATE'),('MM') )) )),(10) )),(rh_concatenate ((lit('Q3')),(lit('-')),(rh_date_to_char (('TRANSACTION_DATE'),('YYYY') )) )),(rh_concatenate ((lit('Q4')),(lit('-')),(rh_date_to_char (('TRANSACTION_DATE'),('YYYY') )) )) )) )) )

我的代码如下所示,

for key, value in exp_list.items():
    print("item key :",key)
    print('item value: ', value)
    if key=='QUARTER':
        tran_df.withColumn(key, eval(value)).show()