寻找并发数据之间的关系
finding relations between co-concurrent data
我有一个看起来像图形数据库的数据框。
import pandas as pd
mycols=['china', 'england', 'france', 'india', 'pakistan', 'taiwan']
df=pd.DataFrame([[0, 0, 0, 3, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 1, 0, 1, 0, 0],
[3, 1, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 4],
[0, 0, 0, 0, 4, 0]], columns=mycols)
df.index=mycols
简化的虚拟数据框如下所示:
china england france india pakistan taiwan
china 0 0 0 3 0 0
england 0 0 1 1 0 0
france 0 1 0 1 0 0
india 3 1 1 0 1 0
pakistan 0 0 0 1 0 4
taiwan 0 0 0 0 4 0
假设一个用户想从中国去印度,有直达路线。
df[df['china'] > 0].index.str.contains('india')
array([ True])
但没有直达英国的路线:
df[df['china'] > 0].index.str.contains('england')
array([False])
在那种情况下,我需要找到共同的国家:
set(df[df.loc['china'] > 0].index.values) & set(df[df.loc['england'] > 0].index.values)
{'india'}
但也有没有共同好友的情况,需要找好友的好友才能到达目的地。例如
set(df[df.loc['china'] > 0].index.values) & set(df[df.loc['taiwan'] > 0].index.values)
1) 在这种情况下,我该如何编写查询 return 中国 - 印度 - 巴基斯坦 - 台湾?
2) 有没有更好的存储方式?或者 SQL like (rows / columns) 可以吗?
你的问题(我假设)基本上是在加权图中找到任意两个给定节点之间的最短路径。从算法上讲,这叫做 Shortest path problem (or more precisely single-pair shortest path problem). Networkx 2.1 has a function shortest_path
正是为了
根据他们的例子,
G = nx.path_graph(5)
>>> print(nx.shortest_path(G, source=0, target=4))
[0, 1, 2, 3, 4]
If the source and target are both specified, return a single list of
nodes in a shortest path from the source to the target.
如果你想得到从一个源到所有节点的最短路径,只需跳过 target
节点(本质上使它成为一个 单源最短路径问题)
您可以使用 Networkx 按以下方式执行此操作
加载图表
import pandas as pd
import networkx as nx
mycols=['china', 'england', 'france', 'india', 'pakistan', 'taiwan']
df=pd.DataFrame([[0, 0, 0, 3, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 1, 0, 1, 0, 0],
[3, 1, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 4],
[0, 0, 0, 0, 4, 0]], columns=mycols)
#Load the graph from dataframe
G = nx.from_numpy_matrix(df.values)
#set the nodes names
G = nx.relabel_nodes(graph, dict(enumerate(mycols)))
测试图表是否正确加载
print G.edges()
#EdgeView([('pakistan', 'taiwan'), ('pakistan', 'india'), ('england', 'india'), ('england', 'france'), ('india', 'china'), ('india', 'france')])
print graph['china']
#AtlasView({'india': {'weight': 3}})
print graph['england']
#AtlasView({'india': {'weight': 1}, 'france': {'weight': 1}})
现在假设您需要找到从 china
到 india
的所有路径
for path in nx.all_simple_paths(graph, source='china', target='taiwan'):
print path
#Output : ['china', 'india', 'pakistan', 'taiwan']
如果你想找到从一个节点到另一个节点的最短路径
for path in nx.all_shortest_paths(graph, source='taiwan', target='india'):
print path
#Output : ['taiwan', 'pakistan', 'india']
您可以找到多种其他算法来查找最短路径、全对最短路径、dijsktra 算法等。at their documentation 以满足您的查询
注意可能存在一种使用from_pandas_dataframe直接从pandas加载图形的方法,但我不确定用例是否正确,因为它需要源和目标
我有一个看起来像图形数据库的数据框。
import pandas as pd
mycols=['china', 'england', 'france', 'india', 'pakistan', 'taiwan']
df=pd.DataFrame([[0, 0, 0, 3, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 1, 0, 1, 0, 0],
[3, 1, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 4],
[0, 0, 0, 0, 4, 0]], columns=mycols)
df.index=mycols
简化的虚拟数据框如下所示:
china england france india pakistan taiwan
china 0 0 0 3 0 0
england 0 0 1 1 0 0
france 0 1 0 1 0 0
india 3 1 1 0 1 0
pakistan 0 0 0 1 0 4
taiwan 0 0 0 0 4 0
假设一个用户想从中国去印度,有直达路线。
df[df['china'] > 0].index.str.contains('india')
array([ True])
但没有直达英国的路线:
df[df['china'] > 0].index.str.contains('england')
array([False])
在那种情况下,我需要找到共同的国家:
set(df[df.loc['china'] > 0].index.values) & set(df[df.loc['england'] > 0].index.values)
{'india'}
但也有没有共同好友的情况,需要找好友的好友才能到达目的地。例如
set(df[df.loc['china'] > 0].index.values) & set(df[df.loc['taiwan'] > 0].index.values)
1) 在这种情况下,我该如何编写查询 return 中国 - 印度 - 巴基斯坦 - 台湾?
2) 有没有更好的存储方式?或者 SQL like (rows / columns) 可以吗?
你的问题(我假设)基本上是在加权图中找到任意两个给定节点之间的最短路径。从算法上讲,这叫做 Shortest path problem (or more precisely single-pair shortest path problem). Networkx 2.1 has a function shortest_path
正是为了
根据他们的例子,
G = nx.path_graph(5)
>>> print(nx.shortest_path(G, source=0, target=4))
[0, 1, 2, 3, 4]
If the source and target are both specified, return a single list of nodes in a shortest path from the source to the target.
如果你想得到从一个源到所有节点的最短路径,只需跳过 target
节点(本质上使它成为一个 单源最短路径问题)
您可以使用 Networkx 按以下方式执行此操作
加载图表
import pandas as pd
import networkx as nx
mycols=['china', 'england', 'france', 'india', 'pakistan', 'taiwan']
df=pd.DataFrame([[0, 0, 0, 3, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 1, 0, 1, 0, 0],
[3, 1, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 4],
[0, 0, 0, 0, 4, 0]], columns=mycols)
#Load the graph from dataframe
G = nx.from_numpy_matrix(df.values)
#set the nodes names
G = nx.relabel_nodes(graph, dict(enumerate(mycols)))
测试图表是否正确加载
print G.edges()
#EdgeView([('pakistan', 'taiwan'), ('pakistan', 'india'), ('england', 'india'), ('england', 'france'), ('india', 'china'), ('india', 'france')])
print graph['china']
#AtlasView({'india': {'weight': 3}})
print graph['england']
#AtlasView({'india': {'weight': 1}, 'france': {'weight': 1}})
现在假设您需要找到从 china
到 india
for path in nx.all_simple_paths(graph, source='china', target='taiwan'):
print path
#Output : ['china', 'india', 'pakistan', 'taiwan']
如果你想找到从一个节点到另一个节点的最短路径
for path in nx.all_shortest_paths(graph, source='taiwan', target='india'):
print path
#Output : ['taiwan', 'pakistan', 'india']
您可以找到多种其他算法来查找最短路径、全对最短路径、dijsktra 算法等。at their documentation 以满足您的查询
注意可能存在一种使用from_pandas_dataframe直接从pandas加载图形的方法,但我不确定用例是否正确,因为它需要源和目标