pyspark生成唯一值的所有组合

时间:2018-11-13 10:37:15

标签: pandas pyspark itertools

我正在尝试在我的spark数据框中生成唯一值的所有组合。 我想到的解决方案需要使用itertools.product和pandas数据框,因此效率不够。 这是我的代码:

all_date = [ i.Date for i in df.select("Date").distinct().collect()]
all_stores_id = [i.ID for i in fd.select("ID").distinct().collect()]
all_category = [i.CATEGORY for i in fd.select("CATEGORY").distinct().collect()]
combined = [all_date, all_stores_id, all_category]
all_combination_pdf= pd.DataFrame(columns = ['Date', 'ID', 'CATEGORY'], data=list(itertools.product(*combined)))
# convert pandas dataframe to spark
all_combination_df = sqlContext.createDataFrame(all_combination_pdf)
joined =  all_combination_df.join(df,["Date","ID","CATEGORY"],how="left")

有什么办法可以将此代码更改为更具爆发力的代码?

======编辑======

我还尝试使用 crossJoin 功能实现此类功能。 这是代码:

test_df = ((df.select('Date').distinct()).crossJoin(df.select('ID').distinct())).crossJoin(df.select('CATEGORY').distinct())
test_df.show(10)

由于某种未知原因而引发以下异常:

An error occurred while calling o305.showString.
: java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.lang.Integer.valueOf(Integer.java:832)

1 个答案:

答案 0 :(得分:0)

您可以以此生成数据框。它只是使用每个列的唯一值创建一个数据框,然后与其他列执行交叉联接(笛卡尔积)。

((df.select('Date').distinct()).crossJoin(df.select('ID').distinct())).crossJoin(df.select('CATEGORY').distinct())

可以将它放在for循环中,并进行一些工作以使其针对其他数据帧自动进行处理。

希望这会有所帮助