Свести XML-фрейм данных в искре - PullRequest
0 голосов
/ 06 ноября 2018
from pyspark.sql.functions import *
def flatten_df(nested_df):
    exist = True
    while exist:
        flat_cols = [c[0] for c in nested_df.dtypes if c[1][:6] != 'struct']
        nested_cols = [c[0] for c in nested_df.dtypes if c[1][:6] == 'struct']
        if len(nested_cols) > 0:
          print(nested_cols)
          flat_df = nested_df.select(flat_cols +
                                     [col("`"+nc+'`.`'+c+"`").alias((nc+'_'+c).replace(".","_"))
                                      for nc in nested_cols
                                      for c in nested_df.select("`"+nc+'`.*').columns])
          nested_df=flat_df
          #break
        else:
          exist = False
    return flat_df
df = sqlContext.read.format("com.databricks.spark.xml").option("rowTag", "GetDocument").load("/FileStore/tables/test.xml")
df1=flatten_df(df)

Вот код, который я использую для выравнивания XML-документа. По сути, я хочу взять xml с вложенным xml и выровнять все это в одну строку без структурированных типов данных, поэтому каждое значение является столбцом. Приведенный выше код работает для тестовых случаев, которые я сделал, но я попробовал очень большой XML, и после пары циклов сглаживания (в цикле while) он завершается со следующей ошибкой:

'Ambiguous reference to fields StructField(_Id,StringType,true), StructField(_id,StringType,true);'

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

Следует отметить, что в качестве типа данных для столбца можно использовать массивы. Я буду разбирать эти массивы для разделения строк на следующем шаге.

Пример обновления

Оригинал DF -

 |-- Order: long (nullable = true)
 |-- attval: string (nullable = true)
 |-- children: struct (nullable = true)
 |    |-- id: string(nullable = true)
 |    |-- att: array (nullable = true)
 |    |    |-- element: struct (containsNull = true)
 |    |    |    |-- Order: long (nullable = true)
 |    |    |    |-- attval: string (nullable = true)

DF после функции -

 |-- Order: long (nullable = true)
 |-- attval: string (nullable = true)
 |-- children_id: string(nullable = true)
 |-- children_att: array (nullable = true)
 |   |-- children_att_element_Order: long (nullable = true)
 |   |-- children_att_element_attval: string (nullable = true)

1 Ответ

0 голосов
/ 29 апреля 2019

Я столкнулся с похожей проблемой и смог разобрать мой XML-файл следующим образом

  1. Установите следующую библиотеку Maven: «com.databricks: spark-xml_2.10: 0.4.1» на Databricks
  2. Загрузите файл в DBFS по следующему пути: FileStore> tables> xml> sample_data
  3. Запустите следующий код:

    data = spark.read.format("com.databricks.spark.xml").option("rootTag", "col1").option("rowTag", "col2").option("rowTag", "col3").load("dbfs:/FileStore/tables/sample_data.xml")
    

    дисплей (данные)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...