我正在用一个带有两列(col1,col2)的假设表解释我的问题,如下所示:
col1 col2
A <--> B
A <--> C
E <--> F
B <--> D
E <--> G
此表位于文件中。在上面的例子中,我想把它分成互斥的关系文件。因此,上表的结果将是两个文件(表):
col1 col2
A <--> B
A <--> C
B <--> D
和
col1 col2
E <--> F
E <--> G
真实文件有数万亿个独特的记录(关系),我想把它分成互斥的关系文件。需要任何智能算法的帮助。我正在使用pyspark从镶木地板文件中读取表格。所以,任何pyspark代码都会非常好但不是必需的(算法更重要)。
答案 0 :(得分:1)
通过“互斥”,你可能意味着没有一个共同的节点。此问题称为图中连接组件的枚举。您可以使用Union-Find技术解决它。
对于每个节点,您将链接关联到属于同一组件的另一个节点。在考虑新关系时,让其中一个成员链接到另一个。
有关详细信息,请参阅https://en.wikipedia.org/wiki/Disjoint-set_data_structure。 这个过程很快,您可以通过所谓的路径压缩技术来加速它。
最后,每个组件都有一个没有链接到任何其他组件的节点,列出所有组件及其包含的节点并不是什么大事。
处理给定示例的步骤可以是
A -> B
C -> A -> B
C -> A -> B, E -> F
C -> A -> B -> D, E -> F
C -> A -> B -> D, E -> F -> G
(你获得线性列表的事实纯粹是偶然的)。
答案 1 :(得分:0)
使用Spark,速度非常快。对于那些处理大数据的人来说,这很有用:
from pyspark import SparkContext
from pyspark.sql.types import *
from pyspark.sql import Row
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, size, length
from pyspark.sql.functions import *
spark = SparkSession.builder \
.appName("Python Spark SQL") \
.config("spark.driver.memory", "32g") \
.config("spark.executor.memory", "32g") \
.config("spark.executor.cores", "12") \
.config("spark.local.dir", "~/mytmp") \
.config("spark.jars.packages", "graphframes:graphframes:0.5.0-spark2.1-s_2.11") \
.getOrCreate()
SparkContext.setSystemProperty('spark.executor.memory', '32g')
sc = spark.sparkContext
df = spark.read.parquet("my_table_file.parquet")
df.registerTempTable("mytable")
# df has two columns : col1 and col2. Similar to hypothetical table presented in my question
v = spark.sql("select col1 as id from mytable union select col2 as id from mytable ")
e = spark.sql("select col1 as src, col2 as dst from mytable")
sc.setCheckpointDir("~/cc_checkpoint")
from graphframes import *
g = GraphFrame(v, e)
connected = g.connectedComponents()
connected.registerTempTable("mytable_connected_components")
connected.select("component").distinct().count()