2017-09-01 16 views
2

私はScalaの新機能です。私はJavaとRでの経験がありますScala/Spark:変更不能なデータフレームとメモリ

私はDataFramesとメモリ管理の不変性について混乱しています。理由は次のとおりです。

Rのデータフレームも不変です。その後、Rにはうまくいかないことが分かった。非常に多数の列で作業する場合、各変換によって新しいDataframeが作成されます(Simplistically put)。 1000の連続する列に対する1000の連続した操作は、1000のデータフレームオブジェクトにつながる)。今では、ほとんどのデータ科学者は、単一のdata.tableオブジェクトで参照によって操作を実行するRのdata.tableを好んでいます。

Scalaのデータフレーム(初心者向け)にも同様の問題があるようです。たとえば、次のコードは1000列の名前を変更するときに1000データフレームを作成するようです。 foldLeft()にもかかわらず、withColumn()を呼び出すたびにDataFrameの新しいインスタンスが作成されます。

私はScalaで非常に効率的なガベージコレクションを信頼していますか、または作成した不変インスタンスの数を制限して試す必要がありますか?後者の場合は、どのようなテクニックを調べるべきですか?

def castAllTypedColumnsTo(df: DataFrame, 
         sourceType: DataType, targetType: DataType): 
DataFrame = 
{ 

val columnsToBeCasted = df.schema 
    .filter(s => s.dataType == sourceType) 

if (columnsToBeCasted.length > 0) 
{ 
    println(s"Found ${columnsToBeCasted.length} columns " + 
    s"(${columnsToBeCasted.map(s => s.name).mkString(",")})" + 
    s" - casting to ${targetType.typeName.capitalize}Type") 
} 

columnsToBeCasted.foldLeft(df) 
{ (foldedDf, col) => 
    castColumnTo(foldedDf, col.name, targetType) 
} 
} 

この方法では、差は、本質的に怠惰である各呼び出し

private def castColumnTo(df: DataFrame, cn: String, tpe: DataType): 
DataFrame = 
{ 

//println("castColumnTo") 
df.withColumn(cn, df(cn).cast(tpe) 

) 
} 

答えて

4

上の新しいインスタンスを返します。返される新しい各DataFrameは、メモリにマテリアライズされません。基本DataFrameとそれに適用する関数を格納するだけです。基本的には、データそのものではなく、データを作成するための実行計画です。

結果を実際に実行してどこかに保存するときは、すべての操作をすべての行に並列に適用できるため、1つの追加出力DataFrameが得られます。 Sparkはできるだけ多くの操作を集約し、不要なものや、保存またはキャッシュするよう明示的に要求されていないものは実現しません。

+0

非常に役立ちます!したがって、上記の文脈であなたの答えを要約すると、私がcastToColumn()関数でデータフレームを宣言していない限り、インスタンスは作成されず、単に "青写真" – Jake

+0

もあります。このトピックに関する合理的にアクセス可能なドキュメントへのリンクを共有していますか? – Jake

+1

データフレームを宣言しても、メモリには生成されません。それはまだ「青写真」です。私はこれについての文書をどこで見つけるか分からない。 Googleはウェブ上でいくつかの議論をするが、公式文書で見つけられる最高のものは、このセクションのスパークRDDに関する1つの段落である:https://spark.apache.org/docs/latest/rdd-programming-guide.html# rdd操作 –

関連する問題