2017-01-27 3 views
2

列A〜Zのデータフレームがあり、他の列の値がnullの場合に基づいてZの値を割り当てたいとします。データフレームの他のすべての列を反復して列の値を決定します。

val df2 = df1.withColumn("Z", 
    when(col("A") === lit(null), lit("Y")) 
    .when(col("B") === lit(null), lit("Y")) 
    .when(col("C") === lit(null), lit("Y")) 
    ... 
    ... 
    .when(col("Y") === lit(null), lit("Y")) 
    .otherwise(lit("N"))); 

withColumnメソッド内で他のすべての列を反復処理するために、より簡潔な方法があります: 私はこれを行うことができますか?

答えて

0

は、私は272個の列ではなく、私は簡単にするために入れていただけで、 ` - Z`を持って、実際に、これを試してみましたspark.sql.functionsパッケージ

val df2 = df1 
    .withColumn("Z",when(array_contains(array(df1.columns.map(c=>lower(col(c))):_*),"null"),lit("Y")).otherwise(lit("N"))) 
0

はい、あなたはwithColumns内の列を反復し、論理式のためfoldLeftを使用することができます。

val df2 = df1.withColumn("Z", 
     when(
     df.columns 
      .filter(name => name.matches("[A-Z]")) // only take these column names 
      .map(name => col(name)) // maps String to Column 
      .foldLeft(lit(false))((acc, current) => when(acc or current.isNull, lit(true)).otherwise(lit(false))) 
     , lit("Y")) 
     .otherwise(lit("N")) 
    ) 

テスト:

入力:

+---+----+----+ 
| A| B| C| 
+---+----+----+ 
| 1| 2| 3| 
| 1|null| 3| 
| 1|null|null| 
+---+----+----+ 

出力:

+---+----+----+---+ 
| A| B| C| Z| 
+---+----+----+---+ 
| 1| 2| 3| N| 
| 1|null| 3| Y| 
| 1|null|null| Y| 
+---+----+----+---+ 
+0

を探索することによって、これを達成しました。だから、150万行のデータセット 'foldLeft'ではうまくいきません。スパークジョブは終了する前に5時間続けられます。 – Gsquare

関連する問題