我正在Apache Spark中尝试Scala shell。 我有一个包含值列表的文本文件,我想查找特定列的平均值。我的input.txt文件如下所示。 (这不是整个文件,而是一个示例。)
<!DOCTYPE html>
<html>
<head>
<script>
function newEl(tag){return document.createElement(tag);}
window.addEventListener('load', mInit, false);
var filenames = ['blueBomb.svg','cpBob.svg'];
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onload = function(){onLoad(this);}
ajax.onerror = function(){console.log("ajax request failed to: "+url);onError(this);}
ajax.open("GET",url,true);
ajax.send();
}
function mInit()
{
filenames.forEach( loadImage );
}
function loadImage(filename)
{
ajaxGet(filename, onLoaded, onFailed);
}
function onLoaded(ajax)
{
var div = newEl('div');
div.innerHTML = ajax.responseText;
document.body.appendChild(div);
}
function onFailed(ajax)
{
console.log('bugger!');
}
</script>
<style>
</style>
</head>
<body>
</body>
</html>
我想在第1列中找到每列第5列的平均值。例如,假设这些是学生ID和标记的集合。对于每个学生ID,我想找到最后一个主题的标记。另请注意,最后一栏中缺少一些值。
这是我到目前为止尝试过的代码。
1 12.4 12.5 18.9 19.9
2 1.7 1.9
3 11.99 1.9 8.9 12.90978933
2 89.987 7.99 12.898980800000
1 12.8 1.88 1.8
2 1.9 1.8 1.8979 1.808888
我想获得最后一列并找到平均值。 作为第一步,我想到了最后一列中的所有值。
val text = sc.textFile("/neerja/input.txt")
val data = text.flatMap(line => line.split("\\t")).map(word => (word,1).reduceByKey(_ + _);
但这给了我val fourth = text.map(_.split("\\t")(4)).collect
。我怀疑它发生是因为最后一列中缺少某些值。请帮我查一下最后一栏的平均值。任何帮助将受到高度赞赏。
答案 0 :(得分:0)
您可以执行以下操作
val text = sc.textFile("/neerja/input.txt")
val fourth = text.map(line => line.split("\\t"))
.map(arr => Try(arr(4).toDouble) getOrElse(0.0)).mean()
println(fourth)
你应该得到第5栏主题的平均值
<强>更新强>
如果需要所有主题列的平均值,我建议您创建dataframe
。 Dataframe
已经过优化RDD
,许多内置函数可用于计算。
要为给定的数据创建dataframe
,您需要schema
。
import org.apache.spark.sql.types.{DoubleType, IntegerType, StructField, StructType}
val schema = StructType(Seq(
StructField("Sn", IntegerType, true),
StructField("subject1", DoubleType, true),
StructField("subject2", DoubleType, true),
StructField("subject3", DoubleType, true),
StructField("subject4", DoubleType, true)
))
RDD[Row]
需要创建为
val data = text.map(line => line.split("\\t"))
.map(arr => Row.fromSeq(Seq(arr(0).toInt, Try(arr(1).asInstanceOf[DoubleType]) getOrElse(0.0),Try(arr(2).toDouble) getOrElse(0.0),Try(arr(3).toDouble) getOrElse(0.0),Try(arr(4).toDouble) getOrElse(0.0))))
最后创建了数据框
val df = sqlContext.createDataFrame(data, schema)
可以使用mean
函数计算每列的平均值
df.select(mean("subject1").as("averageOFS1"),mean("subject2").as("averageOFS2"),mean("subject3").as("averageOFS3"),mean("subject4").as("averageOFS4")).show(false)
应该给你dataframe
+------------------+-----------------+-----------+-----------------+
|averageOFS1 |averageOFS2 |averageOFS3|averageOFS4 |
+------------------+-----------------+-----------+-----------------+
|21.796166666666668|4.661666666666666|5.24965 |7.919609688333335|
+------------------+-----------------+-----------+-----------------+
答案 1 :(得分:0)
如果你想尝试一种结构方法,你也可以使用Dataframes来实现这个目标:
object average extends App{
val sparkSession = SparkSession.builder
.master("local")
.appName("example")
.getOrCreate()
import sparkSession.implicits._
val x = sparkSession.read
.option("header", "false")
.option("delimiter", "\\t")
.option("mode", "FAILFAST")
.csv("...Spark-2.x/src/main/resources/tab_data.csv")
x.printSchema()
x.show(truncate = false)
val df: DataFrame = x.select('_c0 as "id",
'_c1 as "sub1",'_c2 as "sub2",'_c3 as "sub3",'_c4 as "sub4")
df.groupBy('id).agg(avg('sub4)).show()
}