2016-09-06 12 views
1

まず、スカラのコレクションのマップの機能を減らすためには初めてのことです。Scala:行列のリストからの項目数をカウントする

私がしようとしているのは、行列の各行(この場合は0からnまでの数)が何回表示されるかです。理想的な出力は、入力行列の同じ行数とリストの長さと同じ数の列を持つ行列です。たとえば :

val counts = matrix.map(r => r.map(x => (x,r.count(_ == x))).groupBy(_._1)) 

どこ最初:私はこれまでのところ、次のされて思い付いたようなマトリックス

1 1 2 
3 1 0 
2 0 2 

を取得したいと思います。この場合、

val list = List(0,1,2) 

val matrix = Array(
    Array(0,1,2,2), 
    Array(0,0,1,0), 
    Array(2,0,2,0)) 

部分(groupByまで)は、各行に対して、種類(要素、数)の対を与える。それから私はこれをグループ化しようとしましたが、期待通りにはうまくいきません。

これはもちろん、私が達成したいと思っているものから非常に遠く離れています。マトリックスの要素を数えているだけです(0にはならないでしょう)。

また、トピックでは、Array [Array [Type]]はScalaの行列を扱うためのベストプラクティスです(線形代数は適用されず、カウントと読み込みが行われることを前提にしています)。

ありがとうございます。

EDIT: 行によって解決されましたが、同じことを列で実行する必要がある場合はどうなりますか?行列が非常に大きいなら、転置は避けなければならないと思います。

matrixの各行 rに対して
+0

デュードは、非受諾質問を変更した後に受け入れ答えをうまく、とても素敵ではない、です。代わりに新しい質問を開くことができます。 –

答えて

1

rでの出現数にlistの各項目iをマップ:ところで

matrix.map(r => list.map(i => r.count(_ == i))) 
+0

私は、リストの各要素について、それをその行のカウントにマッピングしてから、このリストを行にマッピングすることを理解しています。 ありがとうございます。 ps:転置演算子を使用せずに列で同じ操作を行う方法は? – Francesco

+0

これはカラム数をカウントするのに役立ちますが、2回の転置操作と1回または2回のタイプ変換に関係します。もっと良い方法があると思います。 matrix.transpose.map(r =>(0〜2)).map (i => r.count(_ == i)))。toList.transpose – Francesco

0

を私はそのような解決策を考え出したが、私はそこにかなり確信していますそれを行うためのよりコンパクトで慣用的な方法です。 foldLeftを使用して

def count_list_row(row: Array[Int], tot_elements: Int): Array[Int] ={ 
     val counts = new Array[Int](tot_elements) 
     for(element <- 0 until tot_elements){ 
     counts(element) = row.count(_ == element) 
     } 
     return counts 
    } 

val counts = matrix.map(r => count_list_row(r,2)) 
0

matrix.map { row => {row.foldLeft(Array(0,0,0))((r,e)=> {if(list.contains(e)) {r(e) += 1}; r})}} 
関連する問題