【问题标题】:pyspark how can I combine column values if columns have a same valuepyspark如果列具有相同的值,我如何组合列值
【发布时间】:2017-12-06 12:04:09
【问题描述】:

我有一个想法,将不同行中的数据框值(列表)与相同的键组合起来。 该组合在不同的行中必须具有相同或更多的值,所以我不能只使用df.groupBy('id') 来获取结果。

以下是示例:

+---------+--------------------+
|id       |num_list            |
+---------+--------------------+
|apple    |[11, 12]            |
|apple    |[11, 13 ,14]        |
|apple    |[10, 22, 25]        |
|banana   |[15, 26]            |
|banana   |[15, 29]            |
|banana   |[15, 27]            |
+---------+--------------------+

我们可以发现id=apple 有两条记录和两个列表,例如:[11, 12],[11, 13, 14],因此它们将合并为一条新记录id=apple,num_list=[11, 12, 13, 14]

id=apple,num_list=[10, 22, 25]不会合并。

这就是我想要的答案:

+---------+--------------------+
|id       |num_list            |
+---------+--------------------+
|apple    |[11, 12, 13, 14]    |
|apple    |[10, 22, 25]        |
|banana   |[15, 26, 27, 29]    |
+---------+--------------------+

编辑:

有些规则我要解释一下。

正如@Usernamenotfound 评论的那样,

假设苹果有三个值[11, 12, 14][9, 13 ,14][12,13,27],答案将是[9, 11, 12, 13 ,14, 27]而不是[9, 11, 12, 13 ,14][12,13,27]

有一些新的例子:

+--------------------+------------+
|                  id|num_list    |
+--------------------+------------+
|apple               |         [0]|
|apple               |         [0]|
|apple               |         [1]|
|apple               |         [1]|
|apple               |         [2]|
|apple               |         [3]|
|apple               |         [4]|
|apple               |         [5]|
|apple               |         [6]|
|apple               |         [6]|
|apple               |         [7]|
|apple               |      [7, 8]|
|apple               |         [9]|
|apple               |         [9]|
|apple               |         [9]|
|apple               |     [9, 10]|
|apple               | [9, 17, 18]|
|apple               |        [10]|
|apple               |        [10]|
|apple               |        [10]|
+--------------------+------------+

如果我尝试来自@mayank 的代码会得到错误的答案。

+--------------------------------+---------------------------------------------------------------------------------------+
|                              id|num_list                                                                               |
+--------------------------------+---------------------------------------------------------------------------------------+
|apple                           |[0]                                                                                    |
|apple                           |[0]                                                                                    |
|apple                           |[1]                                                                                    |
|apple                           |[2]                                                                                    |
|apple                           |[3]                                                                                    |
|apple                           |[4]                                                                                    |
|apple                           |[5]                                                                                    |
|apple                           |[6]                                                                                    |
|apple                           |[8, 7]                                                                                 |
|apple                           |[9, 10, 11, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 36, 37, 38]|
|apple                           |[12]                                                                                   |
|apple                           |[14]                                                                                   |
|apple                           |[24]                                                                                   |
|apple                           |[31]                                                                                   |
|apple                           |[32]                                                                                   |
|apple                           |[33, 34]                                                                               |
|apple                           |[35]                                                                                   |
|apple                           |[39]                                                                                   |
+--------------------------------+---------------------------------------------------------------------------------------+

任何帮助将不胜感激。

【问题讨论】:

  • 可以先爆炸,然后做一个groupBy和collect_set。或者写一个 UDF。
  • @philantrovert 如果我使用explode,然后groupBy 将在结果中结合[10, 22, 25],这不是我想要的答案。
  • 哦,知道了。对于彼此相邻的行。
  • 是否只合并num_list 中第一个列表项相同的项?
  • @philantrovert 你有什么想法来处理这个组合吗?

标签: python python-3.x python-2.7 apache-spark pyspark


【解决方案1】:

也许不是最有效的解决方案,但它可以解决您的问题。

import pyspark.sql.functions as F
from pyspark.sql.types import *

def get_combinations(lis):
   final = []

   for li in lis:
       if [y for y in final if [z for z in li if z in y]]:
           found = [y for y in final if [z for z in li if z in y]][0]
           to_add = list(set(found + li))
           final[final.index(found)] = to_add
       else:
           final.append(li)
   return final

apply_udf = F.udf(lambda x:get_combinations(x),ArrayType(ArrayType(IntegerType())))

df = df.groupby('id').agg(F.collect_list('num_list').alias('num_list'))\
        .select(['id', F.explode(apply_udf('num_list')).alias('num_list')])

【讨论】:

  • 我尝试了代码,但我很困惑,如果我更改了不同的数据集,代码会得到错误的答案。我更新了上面的例子。谢谢!
  • 如果我只测试 get_combinations 函数 num_list=[[0], [0], [1], [1], [2], [3], [4], [5 ], [6], [6], [7], [7, 8], [9], [9], [9], [9, 10]],会得到错误的答案。我想不通。
  • 您在上面的编辑中解释的内容适用于此代码。如果两个或多个列表将具有至少一个公共值,则它们将与 set 合并为一个(这会导致删除重复的元素)。如果两个列表没有任何共同值,它们将成为两个单独的记录。行 if any(y for y in final if any(z for z in li if z in y)) 确保了这一点。
  • 对于你上面说的num_list,你到底想要什么结果?
  • 好的,我遇到了问题。任何([0])返回假。我已经进行了必要的更改。立即尝试。
猜你喜欢
  • 2021-12-30
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-29
相关资源
最近更新 更多