2017-07-21 14 views
0

は私が...私の問題があり、これにはかなり新しいです:ケースクラスDataframe dfcase class testclass(date_key: String , amount: Int, type:String, condition1:String, condition2: String)Scala - ケースクラスでGroupByとSumを実行する方法は?

のために、私はtype:String、行のcondition1=condition2

IによってそれをGROUPBY、amountを合計しようとしています関数を定義しようとしていますが、どうすればいいですか?どうもありがとう!あなたは最終的に、その後

  • 値としてキーとケースクラスのリストとしてあなたのデータ型を与えgroupByデータ型は、リスト上の金額を合計あなたのデータ収集最初data.condition1.equals(data.condition2)
  • をフィルタリングする必要が

    `def sumAmount (t: testclass): Int = { 
         if (condition1==condition2) 
        { 
    
        } else { 
         "na" 
        } 
        }` 
    
  • +0

    'condition1 == condition2'が成立したときに' groupBy' ** **のみを実行しようとしていますか?条件が成立していないときとそうでないときに、入力データセットと出力を表示できますか?それは大変感謝しています。 –

    答えて

    2

    は、私はあなたがすでにdataframeは、私はあなたに

    +----------+------+------+----------+----------+ 
    |date_key |amount|types |condition1|condition2| 
    +----------+------+------+----------+----------+ 
    |2015-01-01|332 |types |condition1|condition1| 
    |2015-01-01|332 |types |condition1|condition1| 
    |2015-01-01|332 |types |condition1|condition2| 
    |2015-01-01|332 |types2|condition1|condition1| 
    |2015-01-01|332 |types2|condition1|condition1| 
    |2015-01-01|332 |types2|condition1|condition1| 
    |2015-01-01|332 |types2|condition1|condition2| 
    +----------+------+------+----------+----------+ 
    
    を与えるべきテスト dataframe

    import sqlContext.implicits._ 
    val df = Seq(
        testclass("2015-01-01", 332, "types", "condition1", "condition1"), 
        testclass("2015-01-01", 332, "types", "condition1", "condition1"), 
        testclass("2015-01-01", 332, "types", "condition1", "condition2"), 
        testclass("2015-01-01", 332, "types2", "condition1", "condition1"), 
        testclass("2015-01-01", 332, "types2", "condition1", "condition1"), 
        testclass("2015-01-01", 332, "types2", "condition1", "condition1"), 
        testclass("2015-01-01", 332, "types2", "condition1", "condition2") 
    ).toDF 
    

    を作成したテスト目的のためにcase class

    case class testclass(date_key: String , amount: Int, types: String, condition1: String, condition2: String) 
    

    を使用して持っていると仮定しています

    NあなたがgroupBytypesの列にsumamountの場合は、condition1 = condtion2としたいと思います。 condition1=condition2とやるgroupBysumaggregationとしては

    df.filter($"condition1" === $"condition2") 
        .groupBy("types") 
        .agg(sum("amount").as("sum")) 
        .show(false) 
    

    を次filter行のみが、あなたがしたい場合は

    +------+---+ 
    |types |sum| 
    +------+---+ 
    |types |664| 
    |types2|996| 
    +------+---+ 
    

    を更新し、望ましい結果を持っている必要があり、そのためにあなたがすることができますdataframeの代わりにdataSetを使用すると、.toDS insteを使用できますあなたはステップのそのdataset代わりdataframe

    の残りの部分は上記のように説明されていることがわかります.toDF

    scala> import sqlContext.implicits._ 
    import sqlContext.implicits._ 
    
    scala> case class testclass(date_key: String , amount: Int, types: String, condition1: String, condition2: String) 
    defined class testclass 
    
    scala> val ds = Seq(
        | testclass("2015-01-01", 332, "types", "condition1", "condition1"), 
        |  testclass("2015-01-01", 332, "types", "condition1", "condition1"), 
        |  testclass("2015-01-01", 332, "types", "condition1", "condition2"), 
        |  testclass("2015-01-01", 332, "types2", "condition1", "condition1"), 
        |  testclass("2015-01-01", 332, "types2", "condition1", "condition2") 
        | ).toDS 
    ds: org.apache.spark.sql.Dataset[testclass] = [date_key: string, amount: int ... 3 more fields] 
    

    としての広告。

    +0

    ありがとうございましたupvote。しかし、私はデータフレーム以外のデータセットで作業しようとしています。特定の型にマップするのではなく、値の型を保持しようとしています。そのため、関数を作成しようとしています。 – user4046073

    +0

    dfからケースクラス、しかし、私はどのように関数を記述するのか知りません。だから私の問題はDSにはないと思いますか? – user4046073

    +0

    なぜ関数を記述したいですか?あなたは少し明確にすることができますか? –

    0
    • (何火花が関与していない

    例値

    case class MyData(dataKey: String, amount: Int, dataType: String, condition1: String, condition2: String) 
    
    val grouped = List(MyData("a", 1000, "type1", "matches1", "matches1"), 
        MyData("b", 1000, "type1", "matches1", "matches1"), 
        MyData("c", 1000, "type1", "matches1", "matches2"), 
        MyData("d", 1000, "type2", "matches1", "matches1") 
    ).filter(data => data.condition1.equals(data.condition2)) 
        .groupBy(_.dataType) 
        .map{ case (dataType, values) => 
        dataType -> values.map(_.amount).sum 
        }.toMap 
    
    grouped("type1") shouldBe 2000 
    grouped("type2") shouldBe 1000 
    
    関連する問題