我有一个数据框,在将结果加入最终DF之前,我以不同的方式独立对其进行了转换。 中间转换的数据帧永远不会在任何“动作”中使用。 只有将所有部分连接在一起后,才可以调用第一个动作。 我的问题是-那么我应该缓存第一个数据帧吗? 示例:
arpu_df=get_arpu_df(..). #.cache() will help here?
sample_by_arpu_ranges=arpu_df.filter("arpu>50").sample(False,0.4)\
.union(
arpu_df.filter("arpu>20 and arpu<=50").sample(False,0.1)
)\
.union(
arpu_df.filter("arpu<=20").sample(False,0.02)
).select("base_subsc_id")
sample_by_arpu_ranges.count()
据我所知, sample
是转型。
我想知道是否arpu_df
部分将被重新计算以应用每个过滤器,还是逻辑计划构建器会理解它可以在计划的不同部分中重用它?
答案 0 :(得分:1)
仅在调用操作后才会触发缓存,因此对于您而言,答案是否。cache
在调用sample_by_arpu_ranges.count()
之前将无益。常见的解决方法是在count()
之后调用费用较低的操作cache()
,然后您的代码将成为下一个代码:
arpu_df=get_arpu_df(..)
arpu_df.cache()
arpu_df.count()
sample_by_arpu_ranges=arpu_df.filter("arpu>50").sample(False,0.4)\
.union(
arpu_df.filter("arpu>20 and arpu<=50").sample(False,0.1)
)\
.union(
arpu_df.filter("arpu<=20").sample(False,0.02)
).select("base_subsc_id")
sample_by_arpu_ranges.count()
答案 1 :(得分:0)
答案在您的问题内。您只有一个动作,因此所有转换都将在那个时候完成。在这种情况下,您不需要持久化(或缓存)数据框。
仅当您需要再次计算转换时,持久化才有用
示例:
arpu_df=get_arpu_df(..)
sample_by_arpu_ranges=arpu_df.filter("arpu>50").sample(False,0.4)\
.union(
arpu_df.filter("arpu>20 and arpu<=50").sample(False,0.1)
)\
.union(
arpu_df.filter("arpu<=20").sample(False,0.02)
).select("base_subsc_id").persist() //here you persist sample_by_arpu_ranges because you know you will have multiple actions on it
sample_by_arpu_ranges.count() // 1st action
sample_by_arpu_ranges.write.parquet("path") // 2nd action
在该示例中,sample_by_arpu_ranges将在第一个动作期间保持不变,因此对于第二个动作,sample_by_arpu_ranges将准备就绪。
->不能一with而就:
arpu_df = spark.read.parquet(path)
sample_by_arpu_ranges=arpu_df.filter(...)
sample_by_arpu_ranges.count()
发生了什么:
->不保留arpu_df或sample_by_arpu_ranges,但您不再需要
->不能持续执行多个操作:
arpu_df = spark.read.parquet(path)
sample_by_arpu_ranges=arpu_df.filter(...)
arpu_df.count()
sample_by_arpu_ranges.count()
发生了什么:
->不保留arpu_df!
sample_by_arpu_ranges.count()
arpu_df = spark.read.parquet(path)//您必须再次阅读!
sample_by_arpu_ranges = arpu_df.filter(...)
计数
->持续执行多个操作:
arpu_df = spark.read.parquet(path).persist
sample_by_arpu_ranges=arpu_df.filter(...)
arpu_df.count()
sample_by_arpu_ranges.count()
发生了什么: