преобразование из родного формата матрицы, обваривание

Итак, этот вопрос связан с вопросом Преобразование матричного формата, ошпаривание

Но теперь я хочу сделать операцию на спине. Итак, я могу сделать это таким образом:

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))

Но там у нас проблема с нулями. Как мы знаем, scalding пропускает поля с нулевыми значениями. Итак, например, мы получили матрицу:

1   0   8   
4   5   6   
0   8   9

В формате scalding это:

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, и я не хочу писать все свои собственные)

Мб есть какие-то методы, и можно ли не пропускать нули в матрице?


person DaunnC    schedule 17.11.2013    source источник


Ответы (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"))
person Oscar Boykin    schedule 14.02.2014
comment
Хм, я вижу, у меня была идея перечислить значения, но я не знал, как это сделать. Спасибо за отличный комментарий! Да, это может привести к тому, что наша матрица будет очень большой, но мне было очень интересно, как мы можем сделать разреженную матрицу не разреженной. p.s. Я не верю, кто ответил на мой вопрос... - person DaunnC; 16.02.2014