为每组pyspark RDD / dataframe

时间:2016-10-27 19:19:24

标签: python pyspark spark-dataframe pyspark-sql apache-spark-dataset

我的数据帧有10,0000列,我必须对每个组应用一些逻辑(键是region和dept)。每组将使用10k列中的最多30列,30列列表来自第二个数据集列“colList”。每组将有2-3百万行。我的方法是按键分组和调用函数,如下所示。但它失败了 - 1. shuffle和2.data组超过2G(可以通过重新分区来解决,但成本很高),3。非常慢

def testfunc(iter):
   <<got some complex business logic which cant be done in spark API>>

resRDD = df.rdd.groupBy(region, dept).map(lambda x: testfunc(x))

输入:

region dept week val0 val1  val2  val3 ... val10000   
 US    CS   1     1    2    1     1   ...  2 
 US    CS   2     1.5  2    3     1   ...  2
 US    CS   3     1    2    2     2.1      2
 US    ELE  1     1.1  2    2     2.1      2
 US    ELE  2     2.1  2    2     2.1      2
 US    ELE  3     1    2    1     2   .... 2
 UE    CS   1     2    2    1     2   .... 2

要为每个组选择的列:(数据集2)

region dept colList   
 US    CS   val0,val10,val100,val2000 
 US    ELE  val2,val5,val800,val900
 UE    CS   val21,val54,val806,val9000

我的第二个解决方案是从输入数据创建一个只有30列的新数据集,并将列重命名为col1到col30。然后使用每个列和组的映射列表。然后我可以应用groupbyKey(假设),这将是Skinner而不是10K列的原始输入。

region dept week col0 col1  col2  col3 ... col30   
 US    CS   1     1    2    1     1   ...  2 
 US    CS   2     1.5  2    3     1   ...  2
 US    CS   3     1    2    2     2.1      2
 US    ELE  1     1.1  2    2     2.1      2
 US    ELE  2     2.1  2    2     2.1      2
 US    ELE  3     1    2    1     2   .... 2
 UE    CS   1     2    2    1     2   .... 2

任何人都可以帮助将输入转换为10K到30列吗?或者任何其他替代方案应该没有问题,以避免分组。

1 个答案:

答案 0 :(得分:0)

您可以使用create_map函数将所有10k列转换为每行映射。现在使用一个UDF,它将map,region和dept并将地图稀释到30列,并确保所有30列的名称始终相同。 最后,您可以将复杂函数包装为接收地图而不是原始10K列。希望这会使它小到足以正常工作。

如果没有,你可以获得一个独特的区域和部门,并假设有足够的区域,你可以循环通过一个和另一个组合。