从整数列表的PySpark数据帧数组中快速检索唯一整数?

从整数列表的PySpark数据帧数组中快速检索唯一整数?,pyspark,Pyspark,假设您有一个Pyspark数据帧,df: DataFrame[set_sid_index: array<int>] 和另一个PySpark数据帧,df2: DataFrame[set_sid_index: array<int>] +--------------------+ | set_sid_index| +--------------------+ | [8, 0, 1]| +--------------------+ DataF

假设您有一个Pyspark数据帧,
df

DataFrame[set_sid_index: array<int>]
和另一个PySpark数据帧,
df2

DataFrame[set_sid_index: array<int>]

+--------------------+
|       set_sid_index|
+--------------------+
|           [8, 0, 1]|
+--------------------+
DataFrame[设置\u sid\u索引:数组]
+--------------------+
|设置sid索引|
+--------------------+
|           [8, 0, 1]|
+--------------------+
如何将
df
数组中的列表元素转换为非
{0,1,8}
(df2的唯一元素)的任何元素都转换为“0”或“1”或“8”

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


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

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

如果第1个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
数组

然后:


是的,这是一个很好的答案。但是,对于我的特定用例,我必须找到
uniq
,它是一组整数列表中的唯一元素。具体来说,在我上面给出的示例中,df2只有一个具有唯一值(0、1、8)的列表。实际上,df2将有多个值重叠的列表。我需要
uniq
=
unique(df2values)
。我该怎么做?@user2205916这是否回答了您的问题?如果是这样,我建议投票并接受它。如果您还有其他问题,为什么不打开另一个问题,我将很乐意为您提供解决方案?当然。我澄清了上述问题。我不确定一个单独的问题是否有意义,因为它实际上是上述问题的一个很小的扩展。谢谢上面的代码生成一个ImportError:无法导入numpy.core.multiarray。我认为错误消息是由于集群的工作节点(?)上没有安装numpy,以及解决方案中的ArrayType()函数调用。是否有一种非numpy数据结构可以代替ArrayType来获得相同的结果?
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]      |
+------------------+
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]