Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala/Spark:不可变数据帧和内存_Scala_Apache Spark - Fatal编程技术网

Scala/Spark:不可变数据帧和内存

Scala/Spark:不可变数据帧和内存,scala,apache-spark,Scala,Apache Spark,我对斯卡拉很陌生。我有Java和R方面的经验 我对数据帧和内存管理的不变性感到困惑。原因是: R中的数据帧也是不可变的。随后,在R中发现它不可行。(简单地说)当处理大量列时,每次转换都会产生一个新的数据帧。1000个连续列上的1000个连续操作将导致1000个数据帧对象)。现在,大多数数据科学家更喜欢R的data.table,它通过引用在单个data.table对象上执行操作 Scala的数据帧(对新手来说)似乎也有类似的问题。例如,以下代码在重命名1000列时似乎创建了1000个数据帧。尽管有

我对斯卡拉很陌生。我有Java和R方面的经验

我对数据帧和内存管理的不变性感到困惑。原因是:

R中的数据帧也是不可变的。随后,在R中发现它不可行。(简单地说)当处理大量列时,每次转换都会产生一个新的数据帧。1000个连续列上的1000个连续操作将导致1000个数据帧对象)。现在,大多数数据科学家更喜欢R的data.table,它通过引用在单个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)

)
}

区别主要在于懒惰。返回的每个新数据帧都不会在内存中具体化。它只存储基本数据帧和应用于它的函数。它本质上是一个如何创建一些数据的执行计划,而不是数据本身


当需要实际执行并将结果保存到某个地方时,所有1000个操作都可以并行地应用于每一行,因此您可以获得1个额外的输出数据帧。Spark将尽可能多的操作浓缩在一起,不会具体化任何不必要的或未明确请求保存或缓存的操作。

非常有用!因此,为了在上面的上下文中总结您的答案,只要我没有在castToColumn()函数中声明dataframe,那么就不会创建实例,只是创建一个“蓝图”,如果不是太繁重,您是否可以共享一个链接到关于此主题的合理可访问文档?即使您声明了dataframe,它也不会在内存中生成。这仍然只是一个“蓝图”。我不知道在哪里可以找到关于这个的文档。谷歌在网上展开了一些讨论,但我在官方文档中找到的最好的一段是关于spark RDD的: