Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从Pyspark中的spark数据帧创建边列表?_Python_Apache Spark_Pyspark_Apache Spark Sql_Graphframes - Fatal编程技术网

Python 如何从Pyspark中的spark数据帧创建边列表?

Python 如何从Pyspark中的spark数据帧创建边列表?,python,apache-spark,pyspark,apache-spark-sql,graphframes,Python,Apache Spark,Pyspark,Apache Spark Sql,Graphframes,我正在pyspark中使用graphframes进行一些图形类型的分析,并想知道从顶点数据帧创建边列表数据帧的最佳方法是什么 例如,下面是我的顶点数据框。我有一个ID列表,它们属于不同的组 +---+-----+ |id |group| +---+-----+ |a |1 | |b |2 | |c |1 | |d |2 | |e |3 | |a |3 | |f |1 | +---+-----+ 我的目标是创建一个边缘列表数据框,以指示出现

我正在pyspark中使用
graphframes
进行一些图形类型的分析,并想知道从顶点数据帧创建边列表数据帧的最佳方法是什么

例如,下面是我的顶点数据框。我有一个ID列表,它们属于不同的组

+---+-----+
|id |group|
+---+-----+
|a  |1    |
|b  |2    |
|c  |1    |
|d  |2    |
|e  |3    |
|a  |3    |
|f  |1    |
+---+-----+
我的目标是创建一个边缘列表数据框,以指示出现在公共组中的ID。请注意,1个id可能出现在多个组中(例如,上面的id a出现在组1和组3中)。下面是我希望获得的边缘列表数据框:

+---+-----+-----+
|src|dst  |group|
+---+-----+-----+
|a  |c    |1    |
|a  |f    |1    |
|c  |f    |1    |
|b  |d    |2    |
|a  |e    |3    |
+---+-----+-----+
提前谢谢

编辑1 不确定这是否是更好的解决方法,但我做了一个变通方法:

导入pyspark.sql.f函数
df=df.withColumn('match',f.collect_set('id')。over(Window.partitionBy('group'))
df=df.select(f.col('id')。别名('src'),
f、 分解('match')。别名('dst'),
f、 col(‘组’))
df=df.withColumn('duplicate_edges',f.array_sort(f.array('src','dst')))
df=(df
.其中(f.col('src')!=f.col('dst'))
.drop_duplicates(子集=['duplicate_Edge']))
.drop('duplicate_edges'))
sort('group','src','dst').show()
输出

+---+---+-----+
|src|dst|group|
+---+---+-----+
|  a|  c|    1|
|  a|  f|    1|
|  c|  f|    1|
|  b|  d|    2|
|  e|  a|    3|
+---+---+-----+
原始答案 试试这个:

导入pyspark.sql.f函数
df=(df
.groupby(“组”)
.agg(f.first('id')。别名('src'),
f、 last('id')。别名('dst'))
df.show()
输出:

+-----+---+---+
|group|src|dst|
+-----+---+---+
|    1|  a|  c|
|    3|  e|  a|
|    2|  b|  d|
+-----+---+---+

您可以进行自连接:

df = df.toDF('src', 'group')
df2 = df.toDF('dst', 'group2')

result = df.join(
    df2,
    (df.group == df2.group2) & (df.src < df2.dst)
).select('src', 'dst', 'group').distinct().orderBy('group', 'src', 'dst')

result.show()
+---+---+-----+
|src|dst|group|
+---+---+-----+
|  a|  c|    1|
|  a|  f|    1|
|  c|  f|    1|
|  b|  d|    2|
|  a|  e|    3|
+---+---+-----+
df=df.toDF('src','group')
df2=df.toDF('dst','group2')
结果=df.join(
df2,
(df.group==df2.group2)和(df.src
如果您再添加一行
(id='f',group=1)
,我们如何知道哪个id是
src
,哪个id是
dst
?是否还有其他列可以对每个组的ID进行排序?@jxc这是一个很好的观点。请参见上面的新示例,包括id='f'和group=1。在我的例子中,src和dst顺序不必固定。只要同一组中的两个id可以显示在同一行中,就可以满足需要。@jxc我正在使用spark 2.3,只需做一个自连接:
df.alias('d1')。连接(df.alias('d2'),['group'])。过滤器(“d1.id
谢谢!这管用!@Kafels的建议绝对正确。但是,不要忘记在代码的开头包含以下内容:
import pyspark.sql.functions as f
谢谢你们的回答,这是一个很好的方法!唯一缺少的是,当我在同一组中有两个以上的ID时,只有第一个和最后一个ID将显示为src和dst,但其他ID将丢失。例如,正如@jxc在评论中提到的,如果我们有另一个记录id='f'和group=1,我希望组1中的a,c,f出现在结果数据帧中。src和dst的顺序其实并不重要。我更新了我在问题中的例子,你能想出一种处理方法吗?谢谢@妈妈检查我的编辑