Spark-根据Scala中两个数组的笛卡尔积创建数据框

时间:2018-06-20 11:11:38

标签: arrays scala apache-spark

我有两个数组:

val customers = Array("Alice", "Bob", "Mike","Charly")
val customersLen = customers.length 
val items = Array("milk", "bread", "butter", "apples", "oranges")
val itemsLen = items.length 
val size = (customersLen*itemsLen)-1

我可以在一个数组中创建这两个数组的笛卡尔积:

val cartesianProd= for(i <- 0 to size) yield (customers(i % customersLen ),items(i % itemsLen ))

输出为:

  

cartesianProd:scala.collection.immutable.IndexedSeq [(String,String)]   =向量((爱丽丝,牛奶),(鲍勃,面包),(迈克,黄油),(Charly,苹果),(爱丽丝,橙色),(鲍勃,牛奶),(迈克,面包),(Charly,黄油) ,   (爱丽丝,苹果),(鲍勃,橘子),(迈克,牛奶),(查理,面包),   (爱丽丝,黄油),(鲍勃,苹果),(迈克,橘子),(查理,牛奶),   (爱丽丝,面包),(鲍勃,黄油),(迈克,苹果),(查理,橘子)

现在,我想从该数组生成一个数据框。重用以前的逻辑,所以我写道:

val dfCustItem = Seq(for(i <- 0 to size ) yield(customers (i % customersLen ),items(i % itemsLen ))).toDF("customer","item")

但是出现以下错误:

  

java.lang.IllegalArgumentException:要求失败:   列不匹配。旧列名(1):值新列名   (2):名称,位于scala.Predef $ .require(Predef.scala:224)处的项目   org.apache.spark.sql.Dataset.toDF(Dataset.scala:397)在   org.apache.spark.sql.DatasetHolder.toDF(DatasetHolder.scala:44)...   48消失了

据我了解,这是因为yield在单个名为value的列中返回对(客户,项目),而toDF期望有两个独立的列(不确定这些列的名称是否相关)

如何解决此问题?即在两个独立的列中产生循环的输出

1 个答案:

答案 0 :(得分:1)

您有一个额外的Seq,因此只需删除它就可以了

val dfCustItem = (for(i <- 0 to size ) yield(customers (i % customersLen ),items(i % itemsLen ))).toDF("customer","item")

说明:

您会看到for(i <- 0 to size) yield (customers(i % customersLen ),items(i % itemsLen ))已经是scala.collection.immutable.IndexedSeq[(String, String)]了,添加Seq会生成Seq[scala.collection.immutable.IndexedSeq[(String, String)]],而您需要的是{{1}中的Tuple2个元素}