2017-10-10 4 views
0

私は以下のようなデータフレームを持っています。Sparkからの書き込み時に、分割されたデータのデータ型を失うことを避ける

itemName, itemCategory 
Name1, C0 
Name2, C1 
Name3, C0 

私は分割された寄木細工のファイルとして、このデータフレームを保存したい:私は戻ってデータを読み込むときに、このデータフレームのために

df.write.mode("overwrite").partitionBy("itemCategory").parquet(path) 

、それは文字列にitemCategoryのデータ型を持つことになります。

しかし、時々、私は以下のように他のテナントからのデータフレームを持っています。この場合

itemName, itemCategory 
Name1, 0 
Name2, 1 
Name3, 0 

リードバックするとき、パーティションとして書き込まれた後に、得られたデータフレームは、itemCategoryのデータ型のintを有するであろう。

寄木張りファイルには、データ型を説明するメタデータがあります。どのようにしてパーティションのデータ型を指定して、Intの代わりにStringとして読み取ることができますか?

+0

は、あなたがそれをCSVまたは推論されるタイプを必要とするファイル形式として読み込まなっています「他の回で、」データフレームに読んだときと仮定することは正しいですか? – ayplam

+0

いいえ、ファイルはパーケット形式ですので、データ型はパーティションキーを除き推論されません。 – suriyanto

答えて

0

partitionBy itemCategoryと同じように、このデータはファイル構造に格納され、実際のCSVファイルには格納されません。私の推測では、Sparkは値に応じてデータ型を推論します。すべての値が整数の場合、列の型はintになります。

一つの簡単な解決策は、データを読んだ後StringTypeに列をキャストするために、次のようになります。

import spark.implicits._ 
df.withColumn("itemCategory", $"itemCategory".cast(StringType)) 

別のオプションは、列自体を複製することです。次に、列の1つがパーティショニングに使用されるため、ファイル構造に保存されます。ただし、他の重複列は、パーケットファイルに通常保存されます。複製を作成するには、単純に使用します。

df.withColumn("itemCategoryCopy", $"itemCategory") 
+0

答えをありがとう。残念ながら、私は問題の問題を単純化しました。私は要求されたパーティションによってデータフレームにファイルを読み込む一般的な寄木細工リーダーを持っているので、この特定のロジックを導入することはかなり難しいでしょう。 – suriyanto

+0

@ suriyanto私は、解決策がそれほどエレガントではありませんが、おそらくあなたを助けることができる代替ソリューションを追加しました。 – Shaido

関連する問題