2017-11-01 8 views
2

ローカルドライブにデータフレームをCSVファイルとして保存しようとしています。しかし、私がそうすると、フォルダが生成され、そのパーティション内にファイルが書き込まれます。これを克服するための提案はありますか?Sparkで単一の(通常の)csvファイルとしてデータを書き込む方法は?

私の要件: コードで指定された実際の名前で通常のcsvファイルを取得するには:

コードスニペット: dataframe.coalesce(1).write.mode("overwrite").format("com.databricks.spark.csv").option("header", "true").csv("E:/dataframe.csv")

答えて

1

TL:DRあなたが配布する環境上でコアコンセプト、シーケンシャルを強制しようとしています。それはうまくできません。

スパークはこのようなユーティリティを提供していません。半分散方式で作成できるようにするには、マルチステップのソース依存プロトコルを実装する必要があります。

  • ヘッダーを書きます。
  • 各パーティションにデータファイルを書き込みます。
  • ファイルをマージし、新しい名前を付けます。

これはアプリケーションが限られているため、小さなファイルの場合にのみ有効で、オブジェクトストアなどのソースによっては非常に高価な場合があります。

もちろん、データを収集し、標準のCSVパーサー(Univoicity、Apache Commons)を使用して、選択したストレージに保存できます。これは順次であり、複数のデータ転送が必要です。

0

これを行う自動方法はありません。ローカルディレクトリは、すべての執行に搭載されている場合は私は2つのソリューション

  • を参照してください。ディレクトリが利用できない場合は目的の名前
  • part-*csvファイルの名前を変更するか、/移動、あなたが行ったように、ファイルを書き込みますが、すべての執行上:

しかし、両方のソリューションは、一種の並列処理とスパークのため、目標を破壊無地のScalaを使用してファイルを作成し、ドライバへ データフレームを収集し。

0

それは可能ではないですが、あなたは、このように代を行うことができます。

dataframe.coalesce(1).write.mode("overwrite").format("com.databricks.spark.csv").option("header", "true").csv("E:/data/") 

import org.apache.hadoop.fs._ 
val fs = FileSystem.get(sc.hadoopConfiguration) 
val filePath = "E:/data/" 
val fileName = fs.globStatus(new Path(filePath+"part*"))(0).getPath.getName 
fs.rename(new Path(filePath+fileName), new Path(filePath+"dataframe.csv")) 
関連する問題