从整数列表的PySpark数据帧数组中快速检索唯一整数?
假设您有一个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
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]