所以这个问题与问题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
这是不正确的。那么,我该如何处理呢?我看到两种可能的变体:
有没有一些方法,我可以避免在矩阵中跳过零?
答案 0 :(得分:1)
Scalding存储数据的稀疏表示。如果你想输出一个密集矩阵(首先,它不会扩展,因为行数会比某些点上的内存大),你需要枚举所有的行和列:
// 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"))