如何在Pyspark中估算数据框的真实大小?

26

如何确定数据框的大小?

现在我根据以下方法估算数据框的实际大小:

headers_size = key for key in df.first().asDict()
rows_size = df.map(lambda row: len(value for key, value in row.asDict()).sum()
total_size = headers_size + rows_size

速度太慢了,我正在寻找更好的方法。


1
你必须收集RDD以确定其大小,因此对于大型数据集来说,它肯定会很慢。 - OneCricketeer
1
我曾想使用SizeEstimator对象来估计RDD的样本。不幸的是,我无法找到在Python中执行此操作的方法。 - TheSilence
我认为这个链接可以回答你的问题。http://spark.apache.org/docs/latest/tuning.html#determining-memory-consumption - OneCricketeer
3
我实际上正在寻找一个Python实现,就像我之前所说的那样。@cricket_007 - TheSilence
2个回答

17

我目前正在使用以下方法,但不确定这是否是最好的方式:

df.persist(StorageLevel.Memory)
df.count()

spark-web的UI界面中,在Storage选项卡下,您可以查看以MB为单位显示的大小,然后我执行unpersist操作以清除内存:

df.unpersist()

谢谢,我可以在存储选项卡中检查大小。非常感谢帮助。 - Athar
如果你有一个非常大的数据集,这可能是一个不好的想法。 - Will Faithfull
如果你有一个非常大的数据集,只需要进行抽样(例如 df.sample(.01))并按照相同的步骤操作。然后你就可以近似计算整个数据集的大小。 - ottovon
使用 df.persist(StorageLevel.MEMORY_AND_DISK) - Aman Sehgal

16

Tamas Szuromi的精彩文章:如何在Pyspark中估算RDD或DataFrame的实际大小

from pyspark.serializers import PickleSerializer, AutoBatchedSerializer
def _to_java_object_rdd(rdd):  
    """ Return a JavaRDD of Object by unpickling
    It will convert each Python object into Java object by Pyrolite, whenever the
    RDD is serialized in batch or not.
    """
    rdd = rdd._reserialize(AutoBatchedSerializer(PickleSerializer()))
    return rdd.ctx._jvm.org.apache.spark.mllib.api.python.SerDe.pythonToJava(rdd._jrdd, True)

JavaObj = _to_java_object_rdd(df.rdd)

nbytes = sc._jvm.org.apache.spark.util.SizeEstimator.estimate(JavaObj)

1
这个应该怎么工作?我已经测试了这段代码,但是在我看来,结果更像是“随机函数”而不是估计值。或者是我误解了它们?我正在使用CDH 5.11.2中的Spark 1.6。 - sdikby
5
无论数据框的大小如何,此代码始终返回相同的大小。它总是返回216MB。 - makansij
我看到的变化非常小——从185,704,232到186,020,448再到187,366,176。然而,记录数从5个变成了2,000,000个再到1,500,000,000个。 - Jie
我使用的是pyspark 2.4.4,但它不起作用,出现了TypeError javaPackage not callable。 - SummersKing
5
不要使用这个。这并不是真正的内存使用情况。它报告了一个包含10亿条记录的DataFrame和另一个包含1000万条记录的DataFrame非常接近的数字。 - Tony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接