2013-11-17 4 views
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 и не хочу писать все из них самостоятельно)

Мб Есть некоторые методы, и я могу избежать пропусков нулей в матрице?

ответ

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")) 
+0

Хм, я вижу, у меня была идея перечислить ценности, но не знала, как это сделать. Thx за отличный комментарий! Да, это может привести к тому, что наша матрица будет очень большой, но для меня было очень интересно, как мы можем сделать разреженную матрицу не редкими. постскриптум Я не верю, кто ответил на мой вопрос ... – DaunnC

 Смежные вопросы

  • Нет связанных вопросов^_^