apache-spark - 如何估计 Spark DataFrame 中每列的字节大小?
问题描述
我有一个非常大的包含许多列的 Spark DataFrame,我想就是否将它们保留在我的管道中做出明智的判断,部分基于它们的大小。“多大”是指缓存此 DataFrame 时 RAM 中的字节大小,我希望这是对处理此数据的计算成本的一个不错的估计。一些列是简单类型(例如双精度、整数),但其他列是复杂类型(例如可变长度的数组和映射)。
我尝试过的一种方法是先缓存 DataFrame,然后再缓存有问题的列,查看 Spark UI 中的 Storage 选项卡,然后获取差异。但对于具有大量列的 DataFrame,这是一个烦人且缓慢的练习。
我通常使用 PySpark,所以 PySpark 答案会更好,但 Scala 也可以。
解决方案
我找到了一个基于此相关答案的解决方案:https ://stackoverflow.com/a/49529028 。
假设我正在使用一个名为的数据框df
和一个名为的SparkSession
对象spark
:
import org.apache.spark.sql.{functions => F}
// force the full dataframe into memory (could specify persistence
// mechanism here to ensure that it's really being cached in RAM)
df.cache()
df.count()
// calculate size of full dataframe
val catalystPlan = df.queryExecution.logical
val dfSizeBytes = spark.sessionState.executePlan(catalystPlan).optimizedPlan.stats.sizeInBytes
for (col <- df.columns) {
println("Working on " + col)
// select all columns except this one:
val subDf = df.select(df.columns.filter(_ != col).map(F.col): _*)
// force subDf into RAM
subDf.cache()
subDf.count()
// calculate size of subDf
val catalystPlan = subDf.queryExecution.logical
val subDfSizeBytes = spark.sessionState.executePlan(catalystPlan).optimizedPlan.stats.sizeInBytes
// size of this column as a fraction of full dataframe
val colSizeFrac = (dfSizeBytes - subDfSizeBytes).toDouble / dfSizeBytes.toDouble
println("Column space fraction is " + colSizeFrac * 100.0 + "%")
subDf.unpersist()
}
一些确认这种方法给出了合理的结果:
- 报告的列大小加起来为 100%。
- 简单类型的列,如整数或双精度数,每行占用预期的 4 个字节或 8 个字节。
推荐阅读
- python - 创建用户时发布请求中的 405 Method Not Allowed 错误
- ruby - 从多数组嵌套哈希红宝石中获取值
- google-cloud-functions - 如何获取违反 Stackdriver 提醒政策的 Cloud Functions 的日志?
- c# - C# 将 ListBox.SelectedItems 复制到另一个变量
- python - 循环通过 Base64 txt 文件批量转换为图像?
- react-select - 如何将 data-testid 属性添加到 react-select 组件
- javascript - 尝试在 foreach 循环内将一些 javascript 嵌入到 laravel 视图中
- python - 如何使用带有apollo-upload-client的graphene-file-upload将graphql中的文件上传到Python数据库并在前端做出反应。?
- python - 管理员端修改django
- mysql - sum 函数返回错误的值