上下文:我的公司位于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'))
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),使其在数千个列上依次显示
有没有人?