0

所以这个问题与问题Transforming matrix format, scalding有关

但现在,我想做背部手术。所以我可以这样做:

Tsv(in, ('row, 'col, 'v))
  .read
  .groupBy('row) { _.sortBy('col).mkString('v, "\t") }
  .mapTo(('row, 'v) -> ('c)) { res : (Long, String) =>
    val (row, v) = res
    v }
  .write(Tsv(out))

但是,在那里,我们遇到了零问题。众所周知,烫伤会跳过零值字段。例如,我们得到矩阵:

1   0   8   
4   5   6   
0   8   9

烫伤格式是:

1   1   1
1   3   8
2   1   4
2   2   5
2   3   6
3   2   8
3   3   9

使用我上面写的函数,我们只能得到:

1   8
4   5   6
8   9

这是不正确的。那么,我该如何处理呢?我看到两种可能的变体:

  1. 想办法,加零(其实不知道怎么插入数据)
  2. 以自己的矩阵格式编写自己的操作(这是不可取的,因为我对 Scalding 矩阵操作感兴趣,并且不想自己编写所有这些操作)

Mb 有一些方法,我可以避免在矩阵中跳过零吗?

4

1 回答 1

1

缩放存储数据的稀疏表示。如果你想输出一个密集的矩阵(首先,它不会缩放,因为在某些时候行会比内存容量大),你需要枚举所有的行和列:

// First, I highly suggest you use the TypedPipe api, as it is easier to get
// big jobs right generally

val mat = // has your matrix in 'row1, 'col1, 'val1
def zero: V = // the zero of your value type 
val rows = IterableSource(0 to 1000, 'row)
val cols = IterableSource(0 to 2000, 'col)
rows.crossWithTiny(cols)
  .leftJoinWithSmaller(('row, 'col) -> ('row1, 'col1), mat)
  .map('val1 -> 'val1) { v: V =>
    if(v == null) // this value should be 0 in your type:
      zero
    else
      v
  }
  .groupBy('row) { 
    _.toList[(Int, V)](('col, 'val1) -> 'cols)
  }
  .map('cols -> 'cols) { cols: List[(Int, V)] =>
    cols.sortBy(_._1).map(_._2).mkString("\t")
  }
  .write(TypedTsv[(Int, String)]("output"))
于 2014-02-14T20:40:01.110 回答