【问题标题】:Quickly retrieve unique integers from PySpark DataFrame array of lists of integers?从整数列表的 PySpark DataFrame 数组中快速检索唯一整数?
【发布时间】:2017-07-10 23:11:34
【问题描述】:

假设你有一个 Pyspark DataFrame,df

DataFrame[set_sid_index: array<int>]

看起来像:

+--------------------+
|       set_sid_index|
+--------------------+
|           [8, 0, 1]|
|              [8, 1]|
|                 [9]|
|                 [0]|
|                 [2]|
|           [0, 1, 3]|
|           [8, 0, 1]|
|[22, 2, 6, 0, 1, 21]|
|  [2, 0, 1, 4, 5, 3]|
|              [0, 1]|
|           [0, 1, 3]|
|              [0, 1]|
|                 [9]|
|      [2, 105, 4, 3]|
+--------------------+

还有另一个 PySpark DataFrame,df2

DataFrame[set_sid_index: array<int>]

+--------------------+
|       set_sid_index|
+--------------------+
|           [8, 0, 1]|
+--------------------+

您将如何转换df 数组中列表的元素,以便任何不是{0, 1, 8}df2 的唯一元素)的元素都转换为“0”或“ 1”还是“8”?

--- 上述段落的澄清---

对于我的特定用例,我必须找到uniq,它是整数列表数组中唯一元素的集合。具体来说,在我上面给出的示例中,df2 只有一个具有唯一值(0、1、8)的列表。实际上,df2 将有多个具有重叠值的列表。我需要uniq = unique(df2values)。我该怎么做?

【问题讨论】:

    标签: pyspark


    【解决方案1】:

    我对您的“转换为 0、1 或 8”感到有些困惑;所以,让我们更准确地说:

    如果第一个df的元素不在数组[0,1,8]中,我们将其转换为0

    鉴于这个资格,让我们开始吧。

    我们有:

    from pyspark.sql.functions import udf
    from pyspark.sql.types import *
    uniq = [8, 0, 1]
    sdf.show()
    +--------------------+
    |       set_sid_index|
    +--------------------+
    |           [8, 0, 1]|
    |              [8, 1]|
    |                 [9]|
    |                 [0]|
    |                 [2]|
    |           [0, 1, 3]|
    |           [8, 0, 1]|
    |[22, 2, 6, 0, 1, 21]|
    |  [2, 0, 1, 4, 5, 3]|
    |              [0, 1]|
    |           [0, 1, 3]|
    |              [0, 1]|
    |                 [9]|
    |      [2, 105, 4, 3]|
    +--------------------+
    
    
    sdf.printSchema()
    root
     |-- set_sid_index: array (nullable = true)
     |    |-- element: long (containsNull = true)
    

    现在让我们定义一个简单的udf 并应用它:

    convertToZero = udf(lambda x: [0 if i not in uniq else i for i in x], ArrayType(IntegerType()))
    sdf.withColumn('set_sid_index', convertToZero(sdf['set_sid_index'])).show(truncate=False)
    +------------------+
    |set_sid_index     |
    +------------------+
    |[8, 0, 1]         |
    |[8, 1]            |
    |[0]               |
    |[0]               |
    |[0]               |
    |[0, 1, 0]         |
    |[8, 0, 1]         |
    |[0, 0, 0, 0, 1, 0]|
    |[0, 0, 1, 0, 0, 0]|
    |[0, 1]            |
    |[0, 1, 0]         |
    |[0, 1]            |
    |[0]               |
    |[0, 0, 0, 0]      |
    +------------------+
    

    更新

    假设您没有现成的uniq 数组。

    然后:

    sdf2.show()
    +--------------------+
    |       set_sid_index|
    +--------------------+
    |[22, 2, 6, 0, 1, 21]|
    |  [2, 0, 1, 4, 5, 3]|
    |              [0, 1]|
    +--------------------+
    
    x = sdf2.withColumn('set_sid_index', explode(sdf2['set_sid_index'])).drop_duplicates().collect()
    uniq = [i[0] for i in x]
    uniq
    [0, 22, 6, 5, 1, 3, 2, 4, 21]
    

    【讨论】:

    • 是的,这是一个很好的答案。不过,对于我的特定用例,我必须找到uniq,它是整数列表数组中唯一元素的集合。具体来说,在我上面给出的示例中,df2 只有一个具有唯一值(0、1、8)的列表。实际上, df2 将有多个具有重叠值的列表。我需要uniq = unique(df2values)。我该怎么做?
    • @user2205916 这是否如所述回答了您的问题?如果是这样,我建议赞成并接受它。如果您还有其他问题,何不提出另一个问题,我很乐意为您提供解决方案?
    • 当然。我澄清了上面的问题。我不确定一个单独的问题是否有意义,因为它实际上是上述问题的一个非常小的扩展。谢谢!
    • 以上代码生成 ImportError: Cannot import numpy.core.multiarray。我相信错误消息是由于我的集群的工作节点(?)上缺少 numpy 安装和解决方案中的 ArrayType() 函数调用。有没有非 numpy 的数据结构可以用来代替 ArrayType 达到同样的效果?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    相关资源
    最近更新 更多