Transformación del formato matriz nativo, escaldado
Pregunta
Entonces esta pregunta está relacionada con la pregunta Formato de matriz de transformación, escaldado
Pero ahora, quiero hacer la operación posterior.Para que pueda hacerlo de tal manera:
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))
Pero, allí, tenemos problemas con los ceros.Como sabemos, el escaldado salta a los campos de valores cero.Así que por ejemplo tenemos matriz:
1 0 8
4 5 6
0 8 9
en formato escaldado es:
1 1 1
1 3 8
2 1 4
2 2 5
2 3 6
3 2 8
3 3 9
Usando mi función que escribí arriba solo podemos obtener:
1 8
4 5 6
8 9
y eso es incorrecto.Entonces, ¿cómo puedo lidiar con eso?Veo dos variantes posibles:
- para encontrar la manera, agregar ceros (en realidad, dunno cómo insertar datos)
- para escribir operaciones propias en formato de matriz propio (es imprenseable, porque estoy interesado en las operaciones de matriz escaldada, y no quiero escribirlos a todos los mismos)
MB ¡Hay algunos métodos, y puedo evitar saltar ceros en Matrix?
Solución
Scalding almacena una representación escasa de los datos.Si desea generar una matriz densa (en primer lugar, que no se escalará, porque las filas serán más grandes que cabe en la memoria en algún momento), deberá enumerar todas las filas y columnas:
// 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"))