Python PySparks/Databricks中两列的图形处理
假设我有以下两列的数据帧Python PySparks/Databricks中两列的图形处理,python,apache-spark-sql,databricks,Python,Apache Spark Sql,Databricks,假设我有以下两列的数据帧 value_1| value_2 ---------------- 1| 2 2| 3 4| 5 6| 5 4| 6 现在我想将我的所有值聚集到一个新的数据框中,其中列ID保存每个出现的值,列cluster\u ID表示以某种方式出现在一起的所有值的最小值: ID | cluster_ID ---------------- 1|
value_1| value_2
----------------
1| 2
2| 3
4| 5
6| 5
4| 6
现在我想将我的所有值聚集到一个新的数据框中,其中列ID保存每个出现的值,列cluster\u ID表示以某种方式出现在一起的所有值的最小值:
ID | cluster_ID
----------------
1| 1
2| 1
3| 1
4| 4
5| 4
6| 4
请注意,即使值1和3现在有直接链接,它们仍然聚集在(1,2,3)集群中,因为它们都有一个与值2的连接
由于我不知道如何用Sparks方法解决这个问题,我尝试了以下方法:
首先,我创建了一个包含所有ID对的列表列表:
[[1, 2], [2, 3], [4, 5], [6, 5], [4, 6]]
然后我创建了一个列表列表,其中每个子列表用以下for循环表示集群:
id_pair_list = [[1, 2], [2, 3], [4, 5], [6, 5], [4, 6]]
duplicate_list = []
for e in id_pair_list:
if not duplicate_list:
duplicate_list = [e]
else:
try:
index = next(i for i, value in enumerate(duplicate_list) if e[0] in value)
updated_list = duplicate_list[index]
updated_list.append(e[1])
duplicate_list[index] = updated_list
except StopIteration:
pass
try:
index = next(i for i, value in enumerate(duplicate_list) if e[1] in value)
updated_list = duplicate_list[index]
updated_list.append(e[0])
duplicate_list[index] = updated_list
except StopIteration:
duplicate_list.append(e)
set_duplicate_list = []
for e in duplicate_list:
set_duplicate_list.append(sorted(list(set(e))))
结果如下所示:
[[1, 2, 3], [4, 5, 6]]
在此之后,我创建了如下的新数据帧:
id_mapping_df = spark.createDataFrame(
[[set_duplicate_list]],
['col']
).select(
F.explode('col').alias('ID')
).withColumn(
'cluster_id',
F.array_min('ID')
).withColumn(
'ID',
F.explode('ID')
)
这给了我最后的结果
。。。但是
不幸的是,这只适用于我的小示例数据集。
当我用更大的真实数据集尝试这一点时,我突然遇到了一个问题,即一些值出现在多个集群子列表中,而事实并非如此
我想这已经发生了,因为带有Sparks的for循环是一种反模式,并且通过在我的4个节点上分配工作负载,Sparks没有保持集群列表的一个恒定状态
如何以更好的方式解决此问题
THX&BR
在我看来,这不像是聚类。如果您想使用Spark进行集群,您可以从下面的链接中找到一些关于从何处开始使用的想法
对我来说,这更像是一个图形问题,而不是聚类问题。在Databricks中,您可以通过将相关GraphFrames库上载到集群来使用GraphFrames。该算法计算出这些组。我使用了graphframes-0.8.0-spark3.0-s_2.12.jar,这取决于Spark(3.x)和Scala版本(2.12.x) 下面是一个简单的例子: 第1单元 细胞2 此时,
组件
数据帧将包含您需要的所有信息:
如果需要,您可以进一步操作它,例如将其保存到临时视图并在其上运行一些常规SQL:
第三单元
第4单元
SQL结果:
如果您的数据已经在数据框中,只需一个选择和一个where过滤器,就可以很容易地从原始数据框生成边缘数据框,例如,请参见此处以获得一个。非常有效-非常感谢!你说得对,我把标题改成了graph processingWow。那看起来很酷。今天我学到了一些新东西。谢谢
%python
from graphframes import *
# Vertices dataframe
v = sqlContext.createDataFrame((
( 1, 2 ), ( 2, 3 ), ( 4, 5 ),
( 6, 5 ), ( 4, 6 )
)).toDF("id", "id2")
## Edge dataframe
e = sqlContext.createDataFrame((
(1, 2, "is linked to"),
(2, 3, "is linked to"),
(4, 5, "is linked to"),
(6, 5, "is linked to"),
(4, 6, "is linked to")
)).toDF("src", "dst", "relationship")
## Create the graph frame
g = GraphFrame(v, e)
print(g)
%python
## The connected components adds a component id to each 'group'
sc.setCheckpointDir("/tmp/graphframes-example-connected-components")
components = g.connectedComponents() ## doesn't work on Spark 1.4
display(components)
%python
components.createOrReplaceTempView("tmp")
%sql
SELECT id, component
FROM tmp
UNION
SELECT id2, component
FROM tmp
ORDER BY 1, 2