![](/img/trans.png)
[英]How to create a DataFrame from RDD of SparseVectors in Java
[英]Create dataframe from rdd objectfile
从保存为目标文件的RDD创建ddf的方法是什么。 我想加载RDD,但没有Java对象,只有一个要用作ddf模式的structtype。
我尝试检索为行
val myrdd = sc.objectFile[org.apache.spark.sql.Row]("/home/bipin/"+name)
但是我明白了
java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为org.apache.spark.sql.Row
有没有办法做到这一点。
编辑
据我了解,我必须将rdd读取为对象数组并将其转换为行。 如果任何人都可以为此提供一种方法,那将是可以接受的。
如果您有一个对象数组,则只需对任何一个数组使用行应用方法。 在代码中将是这样的:
val myrdd = sc.objectFile[Array[Object]]("/home/bipin/"+name).map(x => Row(x))
编辑
您是严格的@ user568109,这将创建一个仅具有一个字段的数据框,该字段将是一个数组,用于解析整个数组,您必须执行以下操作:
val myrdd = sc.objectFile[Array[Object]]("/home/bipin/"+name).map(x => Row.fromSeq(x.toSeq))
正如@ user568109所说,还有其他方法可以做到这一点:
val myrdd = sc.objectFile[Array[Object]]("/home/bipin/"+name).map(x => Row(x:_*))
不管您选择哪一个,因为两者都是相同代码的包装:
/**
* This method can be used to construct a [[Row]] with the given values.
*/
def apply(values: Any*): Row = new GenericRow(values.toArray)
/**
* This method can be used to construct a [[Row]] from a [[Seq]] of values.
*/
def fromSeq(values: Seq[Any]): Row = new GenericRow(values.toArray)
让我补充一些解释,
假设您有一个包含3列(项目,类别,价格)的mysql表食品杂货,其内容如下
+------------+---------+----------+-------+
| grocery_id | item | category | price |
+------------+---------+----------+-------+
| 1 | tomato | veg | 2.40 |
| 2 | raddish | veg | 4.30 |
| 3 | banana | fruit | 1.20 |
| 4 | carrot | veg | 2.50 |
| 5 | apple | fruit | 8.10 |
+------------+---------+----------+-------+
5 rows in set (0.00 sec)
现在,在您想要阅读的Spark中,您的代码将如下所示
val groceryRDD = new JdbcRDD(sc, ()=> DriverManager.getConnection(url,uname,passwd), "select item,price from grocery limit ?,?",1,10,2,r => r.getString("item")+"|"+r.getString("price"))
注意:在上面的语句中,我将ResultSet转换为String r => r.getString(“ item”)+“ |” + r.getString(“ price”)
所以我的JdbcRDD将是
groceryRDD: org.apache.spark.rdd.JdbcRDD[String] = JdbcRDD[29] at JdbcRDD at <console>:21
现在保存。
groceryRDD.saveAsObjectFile("/user/cloudera/jdbcobject")
回答你的问题
在读取目标文件时,您需要编写如下内容,
val newJdbObjectFile = sc.objectFile[String]("/user/cloudera/jdbcobject")
以盲目方式,仅替换要保存的RDD的Parameter类型 。
就我而言,杂货RDD的类型参数为String,因此我使用了相同的参数
更新:
就您而言,正如jlopezmat所述,您需要使用Array [Object]
在这里,RDD的每一行都是Object ,但是由于您已经使用ObjectArray进行了转换,因此每行及其内容将再次保存为Array,
即,就我而言,如果保存在RDD上方,如下所示,
val groceryRDD = new JdbcRDD(sc, ()=> DriverManager.getConnection(url,uname,passwd), "select item,price from grocery limit ?,?",1,10,2,r => JdbcRDD.resultSetToObjectArray(r))
当我阅读相同的内容并收集数据时
val newJdbcObjectArrayRDD = sc.objectFile[Array[Object]]("...")
val result = newJdbObjectArrayRDD.collect
结果将为Array [Array [Object]]类型
result: Array[Array[Object]] = Array(Array(raddish, 4.3), Array(banana, 1.2), Array(carrot, 2.5), Array(apple, 8.1))
您可以根据列定义来解析以上内容。
请让我知道它是否回答了您的问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.