1

スパーク コレクションの開始文字あたりの平均単語長を計算できます

val animals23 = sc.parallelize(List(("a","ant"), ("c","crocodile"), ("c","cheetah"), ("c","cat"), ("d","dolphin"), ("d","dog"), ("g","gnu"), ("l","leopard"), ("l","lion"), ("s","spider"), ("t","tiger"), ("w","whale")), 2)

どちらか

animals23.
    aggregateByKey((0,0))(
        (x, y) => (x._1 + y.length, x._2 + 1),
        (x, y) => (x._1 + y._1, x._2 + y._2)
    ).
    map(x => (x._1, x._2._1.toDouble / x._2._2.toDouble)).
    collect

または

animals23.
    combineByKey(
        (x:String) => (x.length,1),
        (x:(Int, Int), y:String) => (x._1 + y.length, x._2 + 1),
        (x:(Int, Int), y:(Int, Int)) => (x._1 + y._1, x._2 + y._2)
    ).
    map(x => (x._1, x._2._1.toDouble / x._2._2.toDouble)).
    collect

それぞれがもたらす

Array((a,3.0), (c,6.333333333333333), (d,5.0), (g,3.0), (l,5.5), (w,5.0), (s,6.0), (t,5.0))

理解できないこと: 2 番目の例の関数では型を明示的に記述する必要があるのに、最初の例の関数はなくてもよいのはなぜですか?

私は話している

(x, y) => (x._1 + y.length, x._2 + 1),
(x, y) => (x._1 + y._1, x._2 + y._2)

(x:(Int, Int), y:String) => (x._1 + y.length, x._2 + 1),
(x:(Int, Int), y:(Int, Int)) => (x._1 + y._1, x._2 + y._2)

それは、Spark の質問というよりはむしろ Scala に関する質問かもしれません。

4

1 に答える 1

2

最初の例の関数はなくてもよいのに、2 番目の例の関数では型を明示的に記述する必要があるのはなぜですか?

最初の例では、コンパイラはseqOp提供された最初の引数リストに基づいて の型を推測できるためです。カリー化aggregateByKeyを使用しています:

def aggregateByKey[U](zeroValue: U)
                     (seqOp: (U, V) ⇒ U, 
                      combOp: (U, U) ⇒ U)
                     (implicit arg0: ClassTag[U]): RDD[(K, U)]

Scala で型推論が機能する方法は、コンパイラが最初の引数リストに基づいて 2 番目の引数リストの型を推論できることです。したがって、最初の例では、それがseqOpfunction((Int, Int), String) => (Int, Int)であることを知っています。同じことが にも当てはまりcombOpます。

それどころか、combineByKey引数リストは 1 つしかありません。

combineByKey[C](createCombiner: (V) ⇒ C, 
                mergeValue: (C, V) ⇒ C, 
                mergeCombiners: (C, C) ⇒ C): RDD[(K, C)] 

また、型を明示的に指定しないと、コンパイラは何を推論xして何を対象とするかを判断できませんy

コンパイラを支援するためにできることは、型引数を明示的に指定することです。

animals23
  .combineByKey[(Int, Int)](x => (x.length,1), 
                           (x, y) => (x._1 + y.length, x._2 + 1),
                           (x, y) => (x._1 + y._1, x._2 + y._2))
  .map(x => (x._1, x._2._1.toDouble / x._2._2.toDouble))
  .collect
于 2016-05-18T12:36:40.537 に答える