2016-08-22 4 views
0

Я пытаюсь переименовать вложенное поле в наборе классов данных с использованием Spark 2.0. Пример следующим образом, где я пытаюсь переименовать «элемент» в «адрес» (сохранение, где он вложен в структуре данных):Переименовать вложенное поле в Scala Spark 2.0 Dataset

df.printSchema 
//Current Output: 
root 
|-- companyAddresses: array (nullable = true) 
| |-- element: struct (containsNull = true) 
| | |-- addressLine: string (nullable = true) 
| | |-- addressCity: string (nullable = true) 
| | |-- addressCountry: string (nullable = true) 
| | |-- url: string (nullable = true) 

//Desired Output: 
root 
|-- companyAddresses: array (nullable = true) 
| |-- address: struct (containsNull = true) 
| | |-- addressLine: string (nullable = true) 
| | |-- addressCity: string (nullable = true) 
| | |-- addressCountry: string (nullable = true) 
| | |-- url: string (nullable = true) 

Для справки, следующий не работает:

df.withColumnRenamed("companyAddresses.element","companyAddresses.address") 
df.withColumnRenamed("companyAddresses.element","address") 
+0

http://stackoverflow.com/questions/35592917/renaming-column-names-of-a-data-frame-in-spark-scala – banjara

+0

@shekhar Эта ссылка содержит только решения для плоских наборов данных, проблема, с которой я сталкиваюсь, - это место, в котором оно расположено. – Nick

ответ

1

То, что вы просите здесь, невозможно. companyAddresses - это массив, а element - это просто не столбец. Это всего лишь индикатор схемы элементов массива. Его нельзя выбрать, и его нельзя переименовать.

Вы можете переименовать только родительский контейнер:

df.withColumnRenamed("companyAddresses", "foo") 

или имена отдельных полей путем изменения схемы. В простых случаях можно также использовать struct и выберите:

df.select(struct($"foo".as("bar"), $"bar".as("foo"))) 

, но очевидно, что это не применимо здесь.

0

Вы могли бы написать небольшую рекурсивную функцию для этого, и использовать карту:

final JavaRDD rdd = df.toJavaRDD().map(row -> ....); 


private static void flatDocument(Row input, Map<String,Object> outValues, String fqn) 
{ 
    final StructType schema = input.schema(); 

    for (StructField field : schema.fields()) 
    { 
     final String fieldName = field.name(); 

     String key = fqn == null ? fieldName : fqn + "_" + fieldName; 

     Object buffer = input.getAs(fieldName); 

     if (field.dataType().getClass().equals(StructType.class)) 
     { 
      if (buffer != null) { 
       flatDocument((Row) buffer, outValues, key); 
      } 
     } 
     else 
     { 
      outValues.put(key, buffer); 
     } 
    } 
} 

Но вам нужна схема, чтобы превратить его обратно в DataSet:/

+0

Thomas, Первоначальный ответ был верным, поскольку этот элемент не является столбцом и, следовательно, не переименовывается. – Nick

+0

Nop, ты сказал, что это невозможно, хотя это так! Я достиг этого с помощью RDD (разлома DF, работа над RDD, затем повторная сборка DF) –

Смежные вопросы