我在How do I convert csv file to rdd尝试了已接受的解决方案,我想要打印除“om”以外的所有用户:
val csv = sc.textFile("file.csv") // original file
val data = csv.map(line => line.split(",").map(elem => elem.trim)) //lines in rows
val header = new SimpleCSVHeader(data.take(1)(0)) // we build our header with the first line
val rows = data.filter(line => header(line,"user") != "om") // filter the header out
val users = rows.map(row => header(row,"user")
users.collect().map(user => println(user))
但是我收到了一个错误:
java.util.NoSuchElementException: key not found: user
我尝试调试它,并在index
中找到header
属性,如下所示:
由于我是spark和scala的新手,这是否意味着user
已经在Map
?那么为什么key not found
错误?
答案 0 :(得分:2)
我发现了我的错误。它与Spark / Scala无关。当我创建示例csv时,我在R:
中使用命令df <- data.frame(user=c('om','daniel','3754978'),topic=c('scala','spark','spark'),hits=c(120,80,1))
write.csv(df, "df.csv",row.names=FALSE)
但默认情况下write.csv
会围绕因素添加"
,这就是为什么地图无法找到关键user
,因为"user"
是真正的关键,使用
write.csv(df, "df.csv",quote=FALSE, row.names=FALSE)
将解决这个问题。
答案 1 :(得分:0)
我重写了示例代码以删除标头方法。 IMO,这个例子提供了一个更容易理解的分步演练。 Here is a more detailed explanation
def main(args: Array[String]): Unit = {
val csv = sc.textFile("/path/to/your/file.csv")
// split / clean data
val headerAndRows = csv.map(line => line.split(",").map(_.trim))
// get header
val header = headerAndRows.first
// filter out header
val data = headerAndRows.filter(_(0) != header(0))
// splits to map (header/value pairs)
val maps = data.map(splits => header.zip(splits).toMap)
// filter out the 'om' user
val result = maps.filter(map => map("user") != "om")
// print result
result.foreach(println)
}