在pyspark数据帧中分发for循环

时间:2019-03-23 14:52:03

标签: python pandas parallel-processing pyspark aggregate-functions

上下文:我的公司位于Spark 2.2中,因此无法使用pandas_udf进行分布式列处理

我的数据框包含数千个列(功能)和数百万条记录

df = spark.createDataFrame([(1,"AB", 100, 200,1), (2, "AC", 150,200,2), (3,"AD", 80,150,0)],["Id","Region","Salary", "HouseHoldIncome", "NumChild"])

我想以并行方式在每列上执行某些摘要和统计,并想知道实现此目的的最佳方法是什么

#The point is any kind of customized summary can exist in my stat1, acting on a Spark dataframe to exploit the distributed processing; of one single column
def stat1(df_1_col):
   if (datatype is not numeric):
      return "NA"
   max_df = df_1_col.groupby().max().collect()
   if (max_df >50):
     return df_1_col.map(....).reduceByKey(...)
   else:
     return get_1st_decile(df_1_col)/df_1_col.agg(mean())

我想实现

+-------+------------------+-------------------+--------------------+
    |col_name|            stat1|       stat2|            stat3|
    +-------+------------------+-------------------+--------------------+
    |  Id|                10|                 10|                  10|
    |Salary|               4.5| 0.5215336029384192|-0.01309370117407197|
    | HouseholdIncome|2.8722813232690143|  0.229328162820653|  0.5756058014772729|
     +-------+------------------+-------------------+--------------------+

这些是我的问题:

1 /没有pandas_udf,如何实现这种分布式处理?

2 /在最坏的情况下,我需要使用for循环。

   col_list = ["Id","Salary", "HouseHoldIncome", "NumChild"]
        for col in col_list:
          ....#how to call stat1[col] properly and collect to final result

我们应该如何正确编写以实现上述形式。据我了解,.withColumn()和udf在这里不能使用,因为它需要collect_list来平整我的列数据框以列出并失去Spark DF的并行处理能力;更不用说我已经尝试了_collect_list_上千万条记录,并且列表太多以致无法处理

.groupBy().agg(stat1_udf(collect_list('data')).alias('data'))

Reference here

3 /如果必须使用for循环,Spark将并行处理所有列吗? 根据{{​​3}},仍然可以并行处理跨列的for循环!但据我所知,这之所以行之有效,是因为它是行明智的,并且仅涉及转换。因此,可以说在for循环步骤中,仅将行式转换添加到DAG 而无需任何评估。因此,我们在DAG中“准备”了df_col1-> Transformation(df_col_1),df_col2-> Transformation(df_col_2)等。在操作步骤,这些将由Spark master分发并并行处理。

但是,对于我来说,这是一个摘要,需要 reduce sum 平均值或某些 collect ,等等。 ,因此每个循环/列都必须先进行评估,然后才能进入下一个循环。DAG无法等待,而必须执行df_col1-> Transformation_and_Action(df_col_1)-> df_col2-> Transformation_and_Action(df_col_2),使其在数千个列上依次显示

有没有人?

0 个答案:

没有答案