spark做描述性统计

spark做描述性统计

在做数据探索性分析的时候,有几个比较重要的数值,,它们能简要的概括数据的分布情况,它们包括分位数、均值、最值等。

在R语言中,有个summary函数,可以返回这些数据摘要
本文所使用的数据集以鸢尾花数据集为例

 summary(iris)

  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100   setosa    :50  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300   versicolor:50  
 Median :5.800   Median :3.000   Median :4.350   Median :1.300   virginica :50  
 Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199                  
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800                  
 Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500 

在spark中也有类似的函数 describe(),但是该函数并没有返回关于分位数的信息

 // 加载鸢尾花数据集
    val irisDF = spark.read
      .options(Map("header" -> "true",
        "nullValue" -> "?",
        "inferSchema" -> "true"))
      .csv(inputFile)
 // dataframe 调用describe 函数 ,因为 “class”列不是数值型的数据,所以在此需要去掉
 val describe = irisDF.drop("class").describe()
  describe.show()

结果如下
spark 的 “summary” 只返回了 计数、均值、方差、最值,因为中值和分位数在大数据上的计算成本很高,两个值都需要先对数据排序再计算。

+-------+------------------+-------------------+------------------+------------------+
|summary|       sepalLength|         sepalWidth|       petalLength|        petalWidth|
+-------+------------------+-------------------+------------------+------------------+
|  count|               150|                150|               150|               150|
|   mean| 5.843333333333335|  3.057333333333334|3.7580000000000027| 1.199333333333334|
| stddev|0.8280661279778637|0.43586628493669793|1.7652982332594662|0.7622376689603467|
|    min|               4.3|                2.0|               1.0|               0.1|
|    max|               7.9|                4.4|               6.9|               2.5|
+-------+------------------+-------------------+------------------+------------------+

在spark2.0之后,提供了 approxQuantile 方法可以计算分位数,用法如下

    //第一个参数   列的名称,可以是单独的列名,也可以是列名数组
    //第二个参数   分位数的值数组 。
    //最后一个参数 表示错误率,数值在 0-1之间 值越小精确度越高
    
    val summary1 = irisDF.stat.approxQuantile(Array("sepalLength", "sepalWidth"),
      Array(0.25, 0.5, 0.75), 0)

    val summary2 = irisDF.stat.approxQuantile("sepalLength", Array(0.25, 0.5, 0.75), 0)

   // summary2 返回的结果是Array(5.1 ,5.8 ,6.4),与R语言的结果一致

为了能让结果更直观我们做进一步的处理,并计算了四分位差IQR

  // 常用的几个数值型变量类型
    val numType = Array(DoubleType, IntegerType, LongType, DecimalType, FloatType)

    val tuples = irisDF.schema.map(sf => {
      (sf.name, sf.dataType)
    }).filter(tp => {
      numType.contains(tp._2)
    }).map(scm => {
      val quantiles = irisDF.stat.approxQuantile(scm._1, Array(0.25, 0.5, 0.75), 0)
      val col = scm._1
      (col, quantiles)
    })

    val quantileDF = tuples
      .toDF("attribute", "quantiles")
      .withColumn("q1", $"quantiles".getItem(0))
      .withColumn("median", $"quantiles".getItem(0))
      .withColumn("q3", $"quantiles".getItem(2))
      .withColumn("IOR", $"q3" - $"q1") // 计算四分位差
      .drop("quantiles")

    quantileDF.show()

结果

+-----------+---+------+---+------------------+
|  attribute| q1|median| q3|               IOR|
+-----------+---+------+---+------------------+
|sepalLength|5.1|   5.1|6.4|1.3000000000000007|
| sepalWidth|2.8|   2.8|3.3|               0.5|
|petalLength|1.6|   1.6|5.1|3.4999999999999996|
| petalWidth|0.3|   0.3|1.8|               1.5|
+-----------+---+------+---+------------------+

我们队之前describe() 的计算结果也做进一步变换

    val schema = describe.schema

    val longForm = describe.flatMap(row => {
      val metric = row.getString(0)
      (1 until row.length).map(i => {
        (metric, schema(i).name, row.getString(i).toDouble)
      })
    })    .toDF("summary", "attribute", "values")

    // 列联表
    val dataset: DataFrame = longForm.groupBy($"attribute")
      .pivot("summary").agg(first("values"))


最后再将两个计算结果join到一起,就可以得到由spark 完成的“summary”结果啦

 quantileDF.join(dataset, "attribute").show()

+-----------+---+------+---+------------------+-----+---+------------------+---+-------------------+
|  attribute| q1|median| q3|               IOR|count|max|              mean|min|             stddev|
+-----------+---+------+---+------------------+-----+---+------------------+---+-------------------+
|petalLength|1.6|   1.6|5.1|3.4999999999999996|150.0|6.9|3.7580000000000027|1.0| 1.7652982332594662|
| sepalWidth|2.8|   2.8|3.3|               0.5|150.0|4.4| 3.057333333333334|2.0|0.43586628493669793|
|sepalLength|5.1|   5.1|6.4|1.3000000000000007|150.0|7.9| 5.843333333333335|4.3| 0.8280661279778637|
| petalWidth|0.3|   0.3|1.8|               1.5|150.0|2.5| 1.199333333333334|0.1| 0.7622376689603467|
+-----------+---+------+---+------------------+-----+---+------------------+---+-------------------+

你可能感兴趣的:(大数据,统计学,spark,大数据)