Как я могу взорвать структуру в кадре данных без жесткого кодирования имен столбцов?
Рассмотрим один из моих наборов данных в качестве примера ниже. Это результат df.printSchema()
member: struct (nullable = true)
| address: struct (nullable = true)
| | city: string (nullable = true)
| | state: string (nullable = true)
| | streetAddress: string (nullable = true)
| | zipCode: string (nullable = true)
| birthDate: string (nullable = true)
| groupIdentification: string (nullable = true)
| memberCode: string (nullable = true)
| patientName: struct (nullable = true)
| | first: string (nullable = true)
| | last: string (nullable = true)
memberContractCode: string (nullable = true)
memberContractType: string (nullable = true)
memberProductCode: string (nullable = true)
Эти данные считываются через json, и я хочу сгладить это, чтобы все находились на одном уровне и чтобы мой фрейм данных содержал только примитивные типы, например:
member.address.city: string (nullable = true)
member.address.state: string (nullable = true)
member.address.streetAddress: string (nullable = true)
member.address.zipCode: string (nullable = true)
member.birthDate: string (nullable = true)
member.groupIdentification: string (nullable = true)
member.memberCode: string (nullable = true)...
Я знаю, что это можно сделать, указав имена столбцов вручную:
df = df.withColumn("member.address.city", df("member.address.city")).withColumn("member.address.state", df("member.address.state"))...
Однако я не смогу жестко закодировать имена столбцов, как указано выше, для всех моих наборов данных, поскольку программа должна иметь возможность обрабатывать новые наборы данных на лету без каких-либо изменений в реальном коде. Я хочу сделать общий метод, который может взорвать любой тип структуры, учитывая, что он уже находится в кадре данных и схема известна (но является подмножеством полной схемы). Возможно ли это в Spark 1.6? И если да, то как
1 ответ
Это должно сделать это - вам нужно будет перебрать схему и "сплющить" ее, обрабатывая поля типа StructType
отдельно от "простых" полей:
// helper recursive method to "flatten" the schema:
def getFields(parent: String, schema: StructType): Seq[String] = schema.fields.flatMap {
case StructField(name, t: StructType, _, _) => getFields(parent + name + ".", t)
case StructField(name, _, _, _) => Seq(s"$parent$name")
}
// apply to our DF's schema:
val fields: Seq[String] = getFields("", df.schema)
// select these fields:
val result = df.select(fields.map(name => $"$name" as name): _*)