Spark Java: как сравнивать схемы, когда столбцы не в том же порядке? - PullRequest
0 голосов
/ 22 октября 2018

После этого вопроса , я теперь запускаю этот код:

List<StructField> fields = new ArrayList<>();
fields.add(DataTypes.createStructField("A",DataTypes.LongType,true));
fields.add(DataTypes.createStructField("B",DataTypes.DoubleType,true));
StructType schema1 = DataTypes.createStructType(fields);
Dataset<Row> df1 = spark.sql("select 1 as A, 2.2 as B");
Dataset<Row> finalDf1 = spark.createDataFrame(df1.javaRDD(), schema1);

fields = new ArrayList<>();
fields.add(DataTypes.createStructField("B",DataTypes.DoubleType,true));
fields.add(DataTypes.createStructField("A",DataTypes.LongType,true));
StructType schema2 = DataTypes.createStructType(fields);
Dataset<Row> df2 = spark.sql("select 2.2 as B, 1 as A");
Dataset<Row> finalDf2 = spark.createDataFrame(df2.javaRDD(), schema2);

finalDf1.printSchema();
finalDf2.printSchema();
System.out.println(finalDf1.schema());
System.out.println(finalDf2.schema());
System.out.println(finalDf1.schema().equals(finalDf2.schema()));

Вот вывод:

root
 |-- A: long (nullable = true)
 |-- B: double (nullable = true)

root
 |-- B: double (nullable = true)
 |-- A: long (nullable = true)

StructType(StructField(A,LongType,true), StructField(B,DoubleType,true))
StructType(StructField(B,DoubleType,true), StructField(A,LongType,true))
false

Хотя столбцы не расположены в том жепорядок, оба этих набора данных имеют одинаковые столбцы и типы столбцов.Какое сравнение требуется здесь для того, чтобы получить true?

Ответы [ 3 ]

0 голосов
/ 22 октября 2018

Если у них другой порядок, то они не одинаковы.даже то, что оба они имеют одинаковое количество столбцов и одинаковые имена.если вы хотите увидеть, имеют ли обе схемы одинаковые имена столбцов, получите схему в списке из обоих Dataframes и напишите код для их сравнения.см. пример Java ниже

public static void main(String[] args)
{

    List<String> firstSchema =Arrays.asList(DataTypes.createStructType(ConfigConstants.firstSchemaFields).fieldNames());
    List<String> secondSchema = Arrays.asList(DataTypes.createStructType(ConfigConstants.secondSchemaFields).fieldNames());


    if(schemasHaveTheSameColumnNames(firstSchema,secondSchema))
    {
        System.out.println("Yes, schemas have the same column names");
    }else
    {
        System.out.println("No, schemas do not have the same column names");
    }
}

private static boolean schemasHaveTheSameColumnNames(List<String> firstSchema, List<String> secondSchema)
{
    if(firstSchema.size() != secondSchema.size())
    {
        return false;
    }else 
    {
        for (String column : secondSchema)
        {
            if(!firstSchema.contains(column))
                return false;
        }
    }
    return true;
}
0 голосов
/ 23 октября 2018

Следуя предыдущим ответам, кажется, что самый быстрый способ сравнить StructFields (столбцы и типы), а не только имена, следующий:

Set<StructField> set1 = new HashSet<>(Arrays.asList(schema1.fields()));
Set<StructField> set2 = new HashSet<>(Arrays.asList(schema2.fields()));
boolean result = set1.equals(set2);
0 голосов
/ 22 октября 2018

Предполагается, что порядковые столбцы не совпадают, и одно и то же имя имеет одинаковую семантику и требуется одинаковое количество столбцов.

Например, используя SCALA, вы сможете настроить JAVA:

import spark.implicits._
val df = sc.parallelize(Seq(
        ("A", "X", 2, 100), ("A", "X", 7, 100), ("B", "X", 10, 100),
        ("C", "X", 1, 100), ("D", "X", 50, 100), ("E", "X", 30, 100)
        )).toDF("c1", "c2", "Val1", "Val2")
val names = df.columns

val df2 = sc.parallelize(Seq(
       ("A", "X", 2, 1))).toDF("c1", "c2", "Val1", "Val2")
val names2 = df2.columns

names.sortWith(_ < _) sameElements names2.sortWith(_ < _)

возвращает true или false, поэкспериментируйте с вводом.

...