web-dev-qa-db-fra.com

Création d'un nouveau DataFrame Spark avec une nouvelle valeur de colonne basée sur la colonne du premier fichier de données Java

Cela devrait être facile mais .... avec Spark 1.6.1 .... J'ai DataFrame # 1 avec les colonnes A, B, C. Avec les valeurs:

A  B  C
1  2  A
2  2  A
3  2  B
4  2  C

Je crée ensuite un nouveau dataframe avec une nouvelle colonne D donc:

DataFrame df2 = df1.withColumn("D", df1.col("C"));

jusqu'ici tout va bien, mais je veux en fait que la valeur de la colonne D soit conditionnelle, c'est-à-dire:

// pseudo code
if (col C = "A") the col D = "X"
else if (col C = "B") the col D = "Y"
else col D = "Z"

Je vais ensuite supprimer la colonne C et renommer D en C. J'ai essayé d'examiner les fonctions de colonne, mais rien ne semble correspondre à la facture; J'ai pensé à utiliser df1.rdd (). Map () et à parcourir les lignes, mais en plus de ne pas réussir à le faire fonctionner, j'ai en quelque sorte pensé que l'objectif de DataFrames était de s'éloigner de l'abstraction RDD? 

Malheureusement, je dois le faire en Java (et bien sûr, Spark avec Java n'est pas optimal !!). Il semble que je manque l’évidence et je suis heureux d’être montré comme un idiot quand on lui présente la solution!

11
user1128482

Je crois que vous pouvez utiliser when pour y parvenir. En outre, vous pouvez probablement remplacer l'ancienne colonne directement. Pour votre exemple, le code serait quelque chose comme:

import static org.Apache.spark.sql.functions.*;

Column newCol = when(col("C").equalTo("A"), "X")
    .when(col("C").equalTo("B"), "Y")
    .otherwise("Z");

DataFrame df2 = df1.withColumn("C", newCol);

Pour plus de détails sur when, consultez/ Column Javadoc .

18
Daniel de Paula

Merci à Daniel, j'ai résolu ça :)

La pièce manquante était l'importation statique des fonctions SQL 

import static org.Apache.spark.sql.functions.*;

Je dois avoir essayé un million de façons différentes d'utiliser quand, mais des erreurs d'échec de compilation/d'exécution ont été enregistrées car je n'ai pas importé. Une fois importée, la réponse de Daniel était parfaite!

2
user1128482

Vous pouvez également utiliser udf pour faire le même travail. Il suffit d'écrire une structure simple if alors else

import org.Apache.spark.sql.functions.udf
val customFunct = udf { d =>
      //if then else construct
    }

val new_DF= df.withColumn(column_name, customFunct(df("data_column")))
1
sudeepgupta90