通过仅从两列中获取唯一值来对pyspark数据框的列进行分组

时间:2019-08-30 04:56:44

标签: pyspark pyspark-sql pyspark-dataframes

我想根据pyspark数据框的两列中的唯一值对一列进行分组。数据帧的输出应该是这样的:一旦有一些值用于groupby,并且如果它存在于另一列中,则不应重复。

    |------------------|-------------------|
    |   fruit          |     fruits        | 
    |------------------|-------------------|
    |    apple         |     banana        |
    |    banana        |     apple         |
    |    apple         |     mango         |
    |    orange        |     guava         |
    |    apple         |    pineapple      |
    |    mango         |    apple          |
    |   banana         |     mango         |
    |   banana         |    pineapple      |
    | -------------------------------------|

我尝试使用单列进行分组,并且需要对其进行修改,或者需要其他逻辑。

df9=final_main.groupBy('fruit').agg(collect_list('fruits').alias('values'))

我正在从上面的查询中获取以下输出;

       |------------------|--------------------------------|
       |   fruit          |     values                     | 
       |------------------|--------------------------------|
       |  apple           | ['banana','mango','pineapple'] |
       |  banana          | ['apple']                      |
       |  orange          | ['guava']                      |
       |  mango           | ['apple']                      |
       |------------------|--------------------------------|

但是我要跟踪输出;

       |------------------|--------------------------------|
       |   fruit          |     values                     | 
       |------------------|--------------------------------|
       |  apple           | ['banana','mango','pineapple'] |
       |  orange          | ['guava']                      |
       |------------------|--------------------------------|

1 个答案:

答案 0 :(得分:1)

这看起来像是连接的组件问题。您可以通过几种方法进行此操作。

1。 GraphFrames

您可以使用GraphFrames包。数据框的每一行都定义了一条边线,您可以使用df作为边线,并使用所有不同水果的数据框作为顶点来创建图形。然后调用connectedComponents方法。然后,您可以操纵输出以获得所需的内容。

2。只是Pyspark

第二种方法有点骇人听闻。为每行创建一个“哈希”,例如

hashed_df = df.withColumn('hash', F.sort_array(F.array(F.col('fruit'), F.col('fruits'))))

删除该列的所有不相同的行

distinct_df = hashed_df.dropDuplicates(['hash'])

再次拆分物品

revert_df = distinct_df.withColumn('fruit', F.col('hash')[0]) \
    .withColumn('fruits', F.col('hash')[1])

按第一列分组

grouped_df = revert_df.groupBy('fruit').agg(F.collect_list('fruits').alias('group'))

如果Pyspark抱怨,您可能需要使用F.concat_ws“哈希化”您的哈希,但是想法是相同的。