오늘의 인기 글
최근 글
최근 댓글
Today
Total
05-03 06:06
관리 메뉴

우노

[Spark] Matrix를 일정 단위로 slice 한 뒤 각각의 nnz, density 구하기 본문

Data/Spark

[Spark] Matrix를 일정 단위로 slice 한 뒤 각각의 nnz, density 구하기

운호(Noah) 2020. 11. 30. 19:05

Matrix를 일정 단위로 slice 한 뒤 각각의 nnz, density 구하기

  • Input

    • Matrix data
    • Matrix data의 행 크기
    • Matrix data의 열 크기
    • Slice 하고자하는 행 크기
    • Slice 하고자하는 열 크기
  • Output

    • Slice 별 nnz
    • Slice 별 density
    • Slice 별 nnz의 평균
    • Slice 별 density의 평균
  • 코드

    • 해당 코드는 (317080,317080) 행렬을 (40000,50000) 단위로 자른것이며 총 42개의 Slice가 발생합니다.

      import scala.collection.mutable.ArrayBuffer
      import scala.math.BigDecimal
      
      // inputfile
      val input = sc.textFile("s3://snapstanford-square-matrix/com-dblp.matrix.txt")
      
      // inputfile의 row, col 크기
      val input_row: Long = 317080
      val input_col: Long = 317080
      
      // slice하고자하는 row, col 단위
      val slice_unit_row = 40000
      val slice_unit_col = 50000
      
      // slice시 col idx 시작 위치와 끝 위치
      var slice_col_start_idx = 0
      var slice_col_end_idx = slice_unit_col-1
      
      // slice별 nnz를 기록할 배열
      val nnz_result = ArrayBuffer[Long]()
      
      // slice별 density를 기록할 배열
      val density_result = ArrayBuffer[scala.math.BigDecimal]()
      
      // col slice
      while (slice_col_end_idx < input_col){
      
        // col을 slice 단위로 자른다.
        val slice_col = input.map{x=>x.split(" ")}.map{x => (x(0).toInt, x(1).toInt, x(2).toDouble)}.filter{x=> x._2 >= slice_col_start_idx && x._2 <= slice_col_end_idx}
      
        // slice시 row idx 시작 위치와 끝 위치
        var slice_row_start_idx = 0
        var slice_row_end_idx = slice_unit_row-1
      
        // row slice 
        while (slice_row_end_idx < input_row){
      
            val slice_row = slice_col.filter{x=> x._1 >= slice_row_start_idx && x._1 <= slice_row_end_idx}
      
            // slice별 nnz를 기록
            val slice_row_col_nnz = slice_row.count
            nnz_result += slice_row_col_nnz
      
            // slice별 density 기록 (소수점 8자리로 반올림)
            val slice_row_col_density = BigDecimal(slice_row_col_nnz.toDouble / (slice_unit_row * slice_unit_col).toDouble).setScale(8, BigDecimal.RoundingMode.HALF_UP)
            density_result += slice_row_col_density
      
            slice_row_start_idx = slice_row_start_idx + slice_unit_row
            slice_row_end_idx = slice_row_end_idx + slice_unit_row
      
        }
      
        slice_col_start_idx = slice_col_start_idx + slice_unit_col
        slice_col_end_idx = slice_col_end_idx + slice_unit_col
      
      }
      
      println("nnz result : " + nnz_result)
      println("\ndensity result : " + density_result)
      println("")
      println("[" + slice_unit_row + "x" + slice_unit_col + "] " + "nnz mean : " + nnz_result.sum / nnz_result.size)
      println("[" + slice_unit_row + "x" + slice_unit_col + "] " + "density mean : " + BigDecimal(density_result.sum.toDouble / density_result.size.toDouble).setScale(8, BigDecimal.RoundingMode.HALF_UP))
      nnz result : ArrayBuffer(235067, 107188, 60790, 45200, 35307, 29440, 22654, 80147, 106590, 77905, 40367, 33267, 27940, 22559, 51045, 47668, 69596, 75780, 30833, 24349, 18505, 36314, 36156, 31452, 44675, 75993, 28137, 20040, 28325, 28634, 24794, 23480, 28322, 77924, 39230, 19214, 21276, 17728, 16609, 16951, 20139, 55994)
      density result : ArrayBuffer(0.00011753, 0.00005359, 0.00003040, 0.00002260, 0.00001765, 0.00001472, 0.00001133, 0.00004007, 0.00005330, 0.00003895, 0.00002018, 0.00001663, 0.00001397, 0.00001128, 0.00002552, 0.00002383, 0.00003480, 0.00003789, 0.00001542, 0.00001217, 0.00000925, 0.00001816, 0.00001808, 0.00001573, 0.00002234, 0.00003800, 0.00001407, 0.00001002, 0.00001416, 0.00001432, 0.00001240, 0.00001174, 0.00001416, 0.00003896, 0.00001962, 0.00000961, 0.00001064, 0.00000886, 0.00000830, 0.00000848, 0.00001007, 0.00002800)
      
      [40000x50000] nnz mean : 46037
      [40000x50000] density mean : 0.00002302
Comments