web-dev-qa-db-fra.com

Comment résoudre AnalysisException: attribut (s) résolu (s) dans Spark

val rdd = sc.parallelize(Seq(("vskp", Array(2.0, 1.0, 2.1, 5.4)),("hyd",Array(1.5, 0.5, 0.9, 3.7)),("hyd", Array(1.5, 0.5, 0.9, 3.2)),("tvm", Array(8.0, 2.9, 9.1, 2.5))))
val df1= rdd.toDF("id", "vals")
val rdd1 = sc.parallelize(Seq(("vskp","ap"),("hyd","tel"),("bglr","kkt")))
val df2 = rdd1.toDF("id", "state")
val df3 = df1.join(df2,df1("id")===df2("id"),"left")

L’opération de jointure fonctionne bien Mais lorsque je réutilise le df2, je suis confronté à une erreur non résolue concernant les attributs

val rdd2 = sc.parallelize(Seq(("vskp", "Y"),("hyd", "N"),("hyd", "N"),("tvm", "Y")))
val df4 = rdd2.toDF("id","existance")
val df5 = df4.join(df2,df4("id")===df2("id"),"left")

ERREUR: org.Apache.spark.sql.AnalysisException: attribut résolu, id # 426.

11
Rajita

Comme mentionné dans mon commentaire, il est lié à https://issues.Apache.org/jira/browse/SPARK-10925 et plus précisément https://issues.Apache.org/jira/browse/SPARK-14948 . La réutilisation de la référence créera une ambiguïté dans le nommage, vous devrez donc cloner le df - voir le dernier commentaire dans https://issues.Apache.org/jira/browse/SPARK-14948 pour un exemple.

15
Erik Schmiegelow

Si vous avez df1 et df2 dérivés de df1, essayez de renommer toutes les colonnes de df2 de sorte qu'aucune des deux colonnes ne porte un nom identique après la jointure. Donc avant la jointure:

donc au lieu de df1.join(df2...

faire

# Step 1 rename shared column names in df2.
df2_renamed = df2.withColumnRenamed('columna', 'column_a_renamed').withColumnRenamed('columnb', 'column_b_renamed')

# Step 2 do the join on the renamed df2 such that no two columns have same name.
df1.join(df2_renamed)
0
Tomer Ben David

J'ai eu le même problème lorsque j'essayais d'utiliser un DataFrame dans deux jointures consécutives.

Voici le problème: DataFrame A a 2 colonnes (appelons-les x et y) et DataFrame B a également 2 colonnes (appelons-les w et z). J'ai besoin de rejoindre A avec B sur x = z, puis de les réunir sur y = z.

(A join B on A.x=B.z) as C join B on C.y=B.z

J'obtenais l'erreur exacte que dans la deuxième jointure, il se plaignait " attribut résolu (s) B.z # 1234 ... ".

Après les liens fournis par @Erik et quelques autres blogs et questions, j'ai compris qu'il me fallait un clone de B.

Voici ce que j'ai fait:

val aDF = ...
val bDF = ...
val bCloned = spark.createDataFrame(bDF.rdd, bDF.schema)
aDF.join(bDF, aDF("x") === bDF("z")).join(bCloned, aDF("y") === bCloned("z"))
0
Iraj Hedayati

Cela fonctionnera si vous faites ce qui suit.

supposons que vous ayez un cadre de données. df1 et si vous voulez croiser la même donnée, vous pouvez utiliser le

df1.toDF("ColA","ColB").as("f_df").join(df1.toDF("ColA","ColB").as("t_df"), 
   $"f_df.pcmdty_id" === 
   $"t_df.assctd_pcmdty_id").select($"f_df.pcmdty_id",$"f_df.assctd_pcmdty_id")
0
dharani sugumar

Pour les développeurs Java, essayez d’appeler cette méthode:

private static Dataset<Row> cloneDataset(Dataset<Row> ds) {
    List<Column> filterColumns = new ArrayList<>();
    List<String> filterColumnsNames = new ArrayList<>();
    scala.collection.Iterator<StructField> it = ds.exprEnc().schema().toIterator();
    while (it.hasNext()) {
        String columnName = it.next().name();
        filterColumns.add(ds.col(columnName));
        filterColumnsNames.add(columnName);
    }
    ds = ds.select(JavaConversions.asScalaBuffer(filterColumns).seq()).toDF(scala.collection.JavaConverters.asScalaIteratorConverter(filterColumnsNames.iterator()).asScala().toSeq());
    return ds;
}

sur les deux jeux de données juste avant la jointure, il clone les jeux de données dans de nouveaux:

df1 = cloneDataset(df1); 
df2 = cloneDataset(df2);
Dataset<Row> join = df1.join(df2, col("column_name"));
// if it didn't work try this
final Dataset<Row> join = cloneDataset(df1.join(df2, columns_seq)); 
0