将 python 列表替换为数据框
Substituting python list for dataframe
我有一个代码可以在我的文本文件中的数据之间创建邻接关系。文件结构非常简单。它只有 2 列描述了 2 个节点之间的连接。例如:
ANALYTICAL_BALANCE BFG_DEPOSIT
CUSTOMER_DETAIL BALANCE
BFG_2056 FFD_15
BALANCE BFG_16
BFG_16 STAT_HIST
ANALYTICAL_BALANCE BFG_2056
CUSTOM_DATA AND_11
AND_11 DICT_DEAL
DICT_DEAL BFG_2056
我现在将数据加载到列表中。
data = [line.split() for line in open('data.txt', sep=' ')
我得到这样的列表
data = [
["ANALYTICAL_BALANCE","BFG_DEPOSIT"],
["CUSTOMER_DETAIL","BALANCE"],
["BFG_2056", "FFD_15"],
["BALANCE","BFG_16"],
["BFG_16","STAT_HIST"],
["ANALYTICAL_BALANCE","BFG_2056"],
["CUSTOM_DATA","AND_11"],
["AND_11","DICT_DEAL"],
["DICT_DEAL","BFG_2056"]
]
然后我创建邻接列表
def create_adj(edges):
adj = {} # or use defaultdict(list) to avoid `if` in the loop below
for a, b in edges:
if not a in adj:
adj[a] = []
if not b in adj:
adj[b] = []
adj[a].append(b)
return adj
和return所有路径
def all_paths(adj):
def recur(path):
node = path[-1]
neighbors = [neighbor for neighbor in adj[node] if not neighbor in path]
if not neighbors:
yield path
for neighbor in neighbors:
yield from recur(path + [neighbor])
for node in adj:
yield from recur([node])
比如我之前给出的例子,输出的数据就是这样的。我不打印长度等于 1 的列表。
adj = create_adj(data)
paths = all_paths(adj)
for i in paths:
if len(i) > 1:
print(i)
output:
['ANALYTICAL_BALANCE', 'BFG_DEPOSIT']
['ANALYTICAL_BALANCE', 'BFG_2056', 'FFD_15']
['CUSTOMER_DETAIL', 'BALANCE', 'BFG_16', 'STAT_HIST']
['BALANCE', 'BFG_16', 'STAT_HIST']
['BFG_2056', 'FFD_15']
['BFG_16', 'STAT_HIST']
['CUSTOM_DATA', 'AND_11', 'DICT_DEAL', 'BFG_2056', 'FFD_15']
['AND_11', 'DICT_DEAL', 'BFG_2056', 'FFD_15']
['DICT_DEAL', 'BFG_2056', 'FFD_15']
虽然数据集很小,但一切都很好,但我在 txt 文件中有将近 13k 行的连接。编译时间太长了。这就是为什么我想将列表上的所有操作更改为 pandas 数据帧。我不知道怎么做,因为我没有这方面的经验。你会怎么做?也许您更清楚我如何实现我的想法。我也在考虑使用 Networkx,但我不知道如何使用它来实现我的代码。任何帮助将不胜感激!
使用 pandas 不会为您加快速度,或者至少不会显着加快,因为 pandas DataFrame 旨在使用表格数据,并没有针对数据的网络结构进行优化。
使用 networkx 肯定会简化您的代码,但恐怕它也不会显着加快您的速度,因为这个库是从纯 python,和你的代码一样。
您将通过使用其他快速库(例如来自 turicreate 的 igraph or the SGraph 对象)获得更好的性能。对于这两个库,需要习惯使用,但两者肯定会为您加快速度。
另一种加快速度的方法当然是为您的问题找到合适且更快的算法。
现在,为了更实际一点,您实际做的是生成图中所有可能的生成树。也许 here 您可以找到一些合适的算法的良好参考,这些算法将以更少的步骤实现您想要的。
还找到了
其中包括一个建议用于查找所有最小生成树的代码的答案。您可以看到它如何创建 networkx 的 Graph
对象并使用该函数。然后你可以给所有的边分配相同的权重,它会在图中找到你所有的生成树。
我有一个代码可以在我的文本文件中的数据之间创建邻接关系。文件结构非常简单。它只有 2 列描述了 2 个节点之间的连接。例如:
ANALYTICAL_BALANCE BFG_DEPOSIT
CUSTOMER_DETAIL BALANCE
BFG_2056 FFD_15
BALANCE BFG_16
BFG_16 STAT_HIST
ANALYTICAL_BALANCE BFG_2056
CUSTOM_DATA AND_11
AND_11 DICT_DEAL
DICT_DEAL BFG_2056
我现在将数据加载到列表中。
data = [line.split() for line in open('data.txt', sep=' ')
我得到这样的列表
data = [
["ANALYTICAL_BALANCE","BFG_DEPOSIT"],
["CUSTOMER_DETAIL","BALANCE"],
["BFG_2056", "FFD_15"],
["BALANCE","BFG_16"],
["BFG_16","STAT_HIST"],
["ANALYTICAL_BALANCE","BFG_2056"],
["CUSTOM_DATA","AND_11"],
["AND_11","DICT_DEAL"],
["DICT_DEAL","BFG_2056"]
]
然后我创建邻接列表
def create_adj(edges):
adj = {} # or use defaultdict(list) to avoid `if` in the loop below
for a, b in edges:
if not a in adj:
adj[a] = []
if not b in adj:
adj[b] = []
adj[a].append(b)
return adj
和return所有路径
def all_paths(adj):
def recur(path):
node = path[-1]
neighbors = [neighbor for neighbor in adj[node] if not neighbor in path]
if not neighbors:
yield path
for neighbor in neighbors:
yield from recur(path + [neighbor])
for node in adj:
yield from recur([node])
比如我之前给出的例子,输出的数据就是这样的。我不打印长度等于 1 的列表。
adj = create_adj(data)
paths = all_paths(adj)
for i in paths:
if len(i) > 1:
print(i)
output:
['ANALYTICAL_BALANCE', 'BFG_DEPOSIT']
['ANALYTICAL_BALANCE', 'BFG_2056', 'FFD_15']
['CUSTOMER_DETAIL', 'BALANCE', 'BFG_16', 'STAT_HIST']
['BALANCE', 'BFG_16', 'STAT_HIST']
['BFG_2056', 'FFD_15']
['BFG_16', 'STAT_HIST']
['CUSTOM_DATA', 'AND_11', 'DICT_DEAL', 'BFG_2056', 'FFD_15']
['AND_11', 'DICT_DEAL', 'BFG_2056', 'FFD_15']
['DICT_DEAL', 'BFG_2056', 'FFD_15']
虽然数据集很小,但一切都很好,但我在 txt 文件中有将近 13k 行的连接。编译时间太长了。这就是为什么我想将列表上的所有操作更改为 pandas 数据帧。我不知道怎么做,因为我没有这方面的经验。你会怎么做?也许您更清楚我如何实现我的想法。我也在考虑使用 Networkx,但我不知道如何使用它来实现我的代码。任何帮助将不胜感激!
使用 pandas 不会为您加快速度,或者至少不会显着加快,因为 pandas DataFrame 旨在使用表格数据,并没有针对数据的网络结构进行优化。
使用 networkx 肯定会简化您的代码,但恐怕它也不会显着加快您的速度,因为这个库是从纯 python,和你的代码一样。
您将通过使用其他快速库(例如来自 turicreate 的 igraph or the SGraph 对象)获得更好的性能。对于这两个库,需要习惯使用,但两者肯定会为您加快速度。
另一种加快速度的方法当然是为您的问题找到合适且更快的算法。
现在,为了更实际一点,您实际做的是生成图中所有可能的生成树。也许 here 您可以找到一些合适的算法的良好参考,这些算法将以更少的步骤实现您想要的。
还找到了Graph
对象并使用该函数。然后你可以给所有的边分配相同的权重,它会在图中找到你所有的生成树。