Apache spark Spark:匹配两个数据帧中的列

Apache spark Spark:匹配两个数据帧中的列,apache-spark,dataframe,apache-spark-sql,Apache Spark,Dataframe,Apache Spark Sql,我有一个如下格式的数据帧 +---+---+------+---+ | sp|sp2|colour|sp3| +---+---+------+---+ | 0| 1| 1| 0| | 1| 0| 0| 1| | 0| 0| 1| 0| +---+---+------+---+ 另一个数据帧包含第一个数据帧中每列的系数。比如说 +------+------+---------+------+ | CE_sp|CE_sp2|CE_colour|CE_sp3

我有一个如下格式的数据帧

+---+---+------+---+
| sp|sp2|colour|sp3|
+---+---+------+---+
|  0|  1|     1|  0|
|  1|  0|     0|  1|
|  0|  0|     1|  0|
+---+---+------+---+
另一个数据帧包含第一个数据帧中每列的系数。比如说

+------+------+---------+------+
| CE_sp|CE_sp2|CE_colour|CE_sp3|
+------+------+---------+------+
|  0.94|  0.31|     0.11|  0.72|
+------+------+---------+------+
现在,我想在第一个数据帧中添加一列,该列是通过添加第二个数据帧的分数计算出来的

例如

+---+---+------+---+-----+
| sp|sp2|colour|sp3|Score|
+---+---+------+---+-----+
|  0|  1|     1|  0| 0.42|
|  1|  0|     0|  1| 1.66|
|  0|  0|     1|  0| 0.11|
+---+---+------+---+-----+
i、 e

可以有n个列,列的顺序可以不同


提前感谢

我相信有很多方法可以完成你想做的事情。在所有情况下,您都不需要第二个数据帧,就像我在评论中所说的那样

这里有一个方法:

import org.apache.spark.ml.feature.{ElementwiseProduct,VectorAssembler}
导入org.apache.spark.mllib.linalg.{Vectors,Vector=>MLVector}
val df=序列((0,1,1,0),(1,0,0,1),(0,0,1,0)).toDF(“sp”、“sp2”、“颜色”、“sp3”)
//你的系数代表一个稠密向量
瓦尔系数=0.94
val coeffSp2=0.31
瓦尔系数=0.11
val coeffSp3=0.72
val weightVectors=Vectors.dense(数组(coeffSp、coeffSp2、coeffscolor、coeffSp3))
//您可以使用VectorAssembler组装特征
val assembler=新向量汇编程序()
.setInputCols(df.columns)//因为您需要对所有列进行计算
.setOutputCol(“特性”)
//一旦这些特征组合起来,我们就可以使用权重向量执行元素级产品
val输出=汇编程序.转换(df)
val transformer=新的ElementwiseProduct()
.setScalingVec(权重向量)
.setInputCol(“功能”)
.setOutputCol(“加权特征”)
//创建一个UDF,对加权向量值求和
导入org.apache.spark.sql.functions.udf
def score=udf((score:MLVector)=>{score.toDense.toArray.sum})
//在加权特征上应用UDF
val分数=transformer.transform(output).withColumn(“分数”,分数(“加权特征))
得分。表演
// +---+---+------+---+-----------------+-------------------+-----+
//| sp | sp2 |颜色| sp3 |特征|加权特征|分数|
// +---+---+------+---+-----------------+-------------------+-----+
// |  0|  1|     1|  0|[0.0,1.0,1.0,0.0]|[0.0,0.31,0.11,0.0]| 0.42|
// |  1|  0|     0|  1|[1.0,0.0,0.0,1.0]|[0.94,0.0,0.0,0.72]| 1.66|
// |  0|  0|     1|  0|    (4,[2],[1.0])|     (4,[2],[0.11])| 0.11|
// +---+---+------+---+-----------------+-------------------+-----+
我希望这有帮助。如果您还有更多问题,请不要犹豫。

快速简单:

import org.apache.spark.sql.functions.col
val df=Seq(
(0, 1, 1, 0), (1, 0, 0, 1), (0, 0, 1, 0)
).toDF(“sp”、“sp2”、“颜色”、“sp3”)
val coefs=Map(“sp”->0.94,“sp2”->0.32,“颜色”->0.11,“sp3”->0.72)
val分数=df.columns.map(
c=>col(c)*coefs.getOrElse(c,0.0)).reduce(u+u)
df.withColumn(“分数”,分数)
在PySpark中也是这样:

从pyspark.sql.functions导入col
df=sc.parallelize([
(0, 1, 1, 0), (1, 0, 0, 1), (0, 0, 1, 0)
]).toDF([“sp”、“sp2”、“颜色”、“sp3”])
coefs={“sp”:0.94,“sp2”:0.32,“color”:0.11,“sp3”:0.72}
带列测向(“分数”,总和(列(c)*系数(c,0)表示测向列中的c)

以下是一个简单的解决方案:

scala> df_wght.show
+-----+------+---------+------+
|ce_sp|ce_sp2|ce_colour|ce_sp3|
+-----+------+---------+------+
|    1|     2|        3|     4|
+-----+------+---------+------+

scala> df.show
+---+---+------+---+
| sp|sp2|colour|sp3|
+---+---+------+---+
|  0|  1|     1|  0|
|  1|  0|     0|  1|
|  0|  0|     1|  0|
+---+---+------+---+
然后我们可以做一个简单的交叉连接和交叉积

val scored = df.join(df_wght).selectExpr("(sp*ce_sp + sp2*ce_sp2 + colour*ce_colour + sp3*ce_sp3) as final_score")
输出:

scala> scored.show
+-----------+                                                                   
|final_score|
+-----------+
|          5|
|          5|
|          3|
+-----------+

那么,您的第二个数据帧实际上包含一行4个值?@eliasah值可以增加,但第二个数据帧中没有任何行始终保持为1。您实际上不需要第二个数据帧DataFrame@eliasah当然请关闭它。你能检查一下你所有的其他问题吗?谢谢。它起作用了。在“.setInputCols(df.columns)//行中,因为您需要对所有列进行计算”,是否可以只选择一些列而不是全部列?我不确定我是否理解您的问题。我有一个带有string和int列的df。我想为所有int列的加权特征添加一列。在上述情况下,所有列(sp、sp2、COLOR、sp3)都用于计算权重。在我的例子中,我只想选择几个列来计算权重列。这可能吗?我试过这样的val字段:数组[字符串]=数组(“sAtt1”,“sAtt2”,“sAtt3”,“sAtt4”,“sAtt5”,“sAtt6”,“sAtt7”,“sAtt8”,“sAtt9”,“sAtt10”)val汇编程序=新向量汇编程序()。setInputCols(字段)。setOutputCol(“特性”)通常是的,您可以。在本例中,我们需要所有列。
scala> scored.show
+-----------+                                                                   
|final_score|
+-----------+
|          5|
|          5|
|          3|
+-----------+