我有两个数组:
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期望有两个独立的列(不确定这些列的名称是否相关)
如何解决此问题?即在两个独立的列中产生循环的输出
答案 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
个元素}