根据另一个数据框的行值在数据框中添加新列

时间:2020-01-09 13:19:18

标签: scala apache-spark apache-spark-sql

我需要向数据帧DF1添加一个新列,但是新列的值应使用该DF中存在的其他列的值来计算。将在另一个数据帧DF2中给出要使用的其他其他列。
例如。 DF1

|protocolNo|serialNum|testMethod  |testProperty|
+----------+---------+------------+------------+       
|Product1  |  AB     |testMethod1 | TP1        |
|Product2  |  CD     |testMethod2 | TP2        |

DF2-

|action| type|               value       |        exploded |
+------------+---------------------------+-----------------+
|append|hash |        [protocolNo]       | protocolNo      |
|append|text |            _              |     _           | 
|append|hash | [serialNum,testProperty]  | serialNum       |
|append|hash | [serialNum,testProperty]  | testProperty    |

现在,如果 type 列的值是 hash <, / strong>。

DF2- 新列应在DF1中创建。该值的计算应如下-

DF1 ~~~这里应该在列的位置出现它们对应的行值。

例如对于DF1的第1行,col值应为

Required

这将导致哈希后产生类似这样的 hash[protocolNo]_hash[serialNumTestProperty]

DF1的每一行都应遵循上述步骤。

我尝试在DF1上使用UDF使用map和withColumn函数。但是在UDF中,外部数据框的值不可访问(给出Null Pointer Exception),同样,我也无法将DataFrame作为UDF的输入。

如上所述,输入DF为DF1和DF2。

所需的输出DF-

hash[Product1]_hash[ABTP1]

newColumn 值是散列后的值

2 个答案:

答案 0 :(得分:0)

您可以代替DF2,将DF2转换为诸如规范之类的案例类,例如

tableView.visibleCells.count

创建上述类的实例

case class Spec(columnName:String,inputColumns:Seq[String],action:String,action:String,type:String*){}

然后您可以处理以下列

val specifications = Seq(
Spec("new_col_name",Seq("serialNum","testProperty"),"hash","append")
                     )

语法可能不正确

答案 1 :(得分:0)

由于DF2具有用于从DF1计算新列的列名,因此我假设DF2不会是巨大的数据框。

第一步是过滤DF2并从DF1中获取我们要选择的列名称。

val hashColumns = DF2.filter('type==="hash").select('exploded).collect

现在,hashcolumns将包含我们要用于计算newColumn中的哈希的列。 hashcolumnsRow的数组。我们需要将其作为Column,以便在DF1中创建newColumn时应用。

val newColumnHash = hashColumns.map(f=>hash(col(f.getString(0)))).reduce(concat_ws("_",_,_))

上面的代码行将Row转换为Column并应用了hash函数。然后我们在连接reduce_。现在,任务变得简单了。我们只需要将此应用到DF1。

DF1.withColumn("newColumn",newColumnHash).show(false)

希望这会有所帮助!