2016-10-21 4 views
2

그래서 xml 파일에서 dataframe을 만듭니다. 여기에는 딜러에 대한 정보가 있고 딜러는 여러 대의 자동차가 있습니다. 각 차량은 cars 요소의 하위 요소이며 value 요소로 표시됩니다. 각 cars.value 요소에는 다양한 자동차 특성이 있습니다. 그래서 다음과 같은 대리점에 대한 각 차량에 대해 하나 개의 행을 작성하는 explode 함수를 사용데이터 프레임에없는 열 선택

exploded_dealer = df.select('dealer_id',explode('cars.value').alias('a_car')) 

을 지금은 cars.value

의 다양한 속성을 얻으려면 나는 이런 식으로 작업을 수행합니다

car_details_df = exploded_dealer.select('dealer_id','a_car.attribute1','a_car.attribute2') 

그리고 잘 작동합니다. 그러나 때로는 cars.value 요소가 내 쿼리에서 지정한 모든 특성을 가지고 있지 않습니다. 그래서 예를 들어 일부 cars.value 요소는 속성 1이있을 수 있습니다 - 그리고 위의 코드를 실행할 때 다음 나는 다음과 같은 오류가 발생합니다 :

pyspark.sql.utils.AnalysisException : u는 "해결할 수없는 주어진 '속성 2' 을 입력 열 : [dealer_id, attribute1]; "

어떻게하면 어쨌든 동일한 쿼리를 실행하도록 spark에 요청합니다. 속성 2의 경우 None을 반환하십시오.

initial_file_df = sqlContext.read.format('com.databricks.spark.xml').options(rowTag='dealer').load('<xml file location>') 

exploded_dealer = df.select('financial_data',explode('cars.value').alias('a_car')) 
+0

이것은 실패한 SQL 쿼리이기 때문에 까다 롭습니다. 파이썬 코드가 아닙니다. 저에게 놀랄 일은 대개 데이터 프레임을위한 하나의 스키마가 있고이 스키마는 속성을 포함 할 수도 있고 그렇지 않을 수도 있습니다. 따라서 버그이거나 데이터 세트를 작성하기 위해 까다로운 작업을 수행 한 것입니다. 그렇다면 지정하십시오. 어쨌든 흥미로운 점은 Spark SQL에 TRY가 없다는 것입니다. 즉, 데이터 프레임을 만들 때 모든 속성을 가진 스키마를 강제하는 등의 해결 방법을 사용해야합니다. – Wilmerton

+0

"보통 데이터 프레임을위한 하나의 스키마가 있다는 것이 놀랍습니다."- 사실은 내 코드가 정적이므로 파일에서 열 a, b, c를 항상 가져올 수 있도록 지정할 수 있습니다. 거기에 있고 나는 그 세 개의 기둥 만 필요합니다. 그러나 언젠가 열 x, b, d가있는 xml이있을 수 있습니다. 그러나 열 c에 대한 데이터가없는 것을 의미하는 경우에도 여전히 a, b, c 만 필요합니다. 그리고 내 코드가 정적이기 때문에 그것은 a, b, c를 요구할 것이고 c가 빠져 있기 때문에 실패 할 것입니다. – Dennis

+0

@Dennis 질문에 대한 대답이 아니라는 것을 알지만 그럼에도 불구하고 도움이 될 수 있습니다. 먼저 스키마를 가져 와서 그에 따라 쿼리를 생성하는 논리를 만들 수 있습니다. – Wilmerton

답변

1

당신은 이미 당신이 할 수있는 최선의 일은 nullable 선택적 필드에 명시 적으로 정의하고 데이터를 가져올 때 사용하는 것입니다 스키마에 대한 특정 가정을하기 때문에 다음과 같이

UPDATE 내 데이터를 읽을.

의은과 유사한 문서를 기대한다고 가정 해 봅시다 :

<rows> 
    <row> 
     <id>1</id> 
     <objects> 
      <object> 
       <attribute1>...</attribute1> 
       ... 
       <attributebN>...</attributeN> 
      </object> 
     </objects> 
    </row> 
</rows> 

attribute1, attribute2, ..., attributebN 주어진 배치에 존재하지 않을 수 있지만, 당신이 선택하고 해당 유형의 유한 집합을 정의 할 수 있습니다.

{("attribute1", StringType), ("attribute2", LongType)} 

당신은 같은 스키마를 정의 할 수 있습니다 :

schema = StructType([ 
    StructField("objects", StructType([ 
    StructField("object", StructType([ 
     StructField("attribute1", StringType(), True), 
     StructField("attribute2", LongType(), True) 
    ]), True) 
    ]), True), 
    StructField("id", LongType(), True) 
]) 

및 독자와 함께 사용 :

spark.read.schema(schema).option("rowTag", "row").format("xml").load(...) 

그것은 어떤 부분 집합 유효합니다 단순화를 위해의이 두 옵션이 있습니다 가정 해 봅시다 ({∅1, {attribute1}, {attribute2}, {attribute1, attribute2}}) 중 하나를 선택합니다. 동시에 스키마 추론에 의존하는 것보다 더 효율적입니다.

관련 문제