Python 将数据框中的两列展开为列表列表
在Pandas数据框中有两列,它们的值在逻辑上彼此跟随。见下文:Python 将数据框中的两列展开为列表列表,python,pandas,list,networkx,Python,Pandas,List,Networkx,在Pandas数据框中有两列,它们的值在逻辑上彼此跟随。见下文: Name Includes Account Product Account Product Account Card Account Card Account Plastic Card Account Token Token Token Vault Account Savings Acco
Name Includes
Account Product Account
Product Account Card Account
Card Account Plastic
Card Account Token
Token Token Vault
Account Savings Account
[['Account', 'Product Account', 'Card Account', 'Plastic'],
['Account', 'Product Account', 'Card Account', 'Token', 'Token Vault'],
['Account', 'Savings Account']]
{'Account': ['Savings Account',
{'Product Account': [{'Card Account': ['Plastic',
{'Token': ['Token Vault']}]}]}]}
所以Account>Product Account>Card Account等等。最终我想创建一个列表列表,其中根(“Account”)是每个列表的第一个元素。输出应如下所示:
Name Includes
Account Product Account
Product Account Card Account
Card Account Plastic
Card Account Token
Token Token Vault
Account Savings Account
[['Account', 'Product Account', 'Card Account', 'Plastic'],
['Account', 'Product Account', 'Card Account', 'Token', 'Token Vault'],
['Account', 'Savings Account']]
{'Account': ['Savings Account',
{'Product Account': [{'Card Account': ['Plastic',
{'Token': ['Token Vault']}]}]}]}
我基本上希望找到可能存在的dataframe元素之间的任何和所有可能的路径。我目前有一段代码可以将两个dataframe列转换为字典结构:
def link_hops(dictionary):
dictionary = dict(df.groupby('Name')['Includes'].apply(set))
dictionary = {k: list(v) for k, v in dictionary.items()}
all_values = set(x for xs in dictionary.values() for x in xs)
refs = all_values & set(dictionary.keys())
for k, v in dictionary.items():
for i in range(len(v)):
if v[i] in refs:
v[i] = {v[i]: v1 for k1, v1 in dictionary.items() if v[i] == k1}
dictionary = {k: v for k, v in dictionary.items() if k not in refs}
return dictionary
我得到以下信息:
Name Includes
Account Product Account
Product Account Card Account
Card Account Plastic
Card Account Token
Token Token Vault
Account Savings Account
[['Account', 'Product Account', 'Card Account', 'Plastic'],
['Account', 'Product Account', 'Card Account', 'Token', 'Token Vault'],
['Account', 'Savings Account']]
{'Account': ['Savings Account',
{'Product Account': [{'Card Account': ['Plastic',
{'Token': ['Token Vault']}]}]}]}
这段代码为每个路径(“储蓄账户”、“塑料”、“令牌保险库”)定义从根(“账户”)到终端的所有路径,但我不知道如何将其转换为可扩展的列表格式。我有一个递归脚本,它可以处理这样的小示例,但是当我通过链接将它们转换为字典时,我正在处理的实际数据帧可能有数百或数千层的深度,并且在调用该脚本时很容易突破递归限制
我想知道是否可以跳过将数据帧转换为字典的中间步骤,直接将其转换为列表列表,甚至可以使用.map()
或类似的方法直接处理数据帧。方法1
这里有一种方法,使用NetworkX
将数据帧中的每一行作为有向图的图边,并查找到不同目标的from帐户:
#方法2
查找图形结束节点的另一种方法是查看,并保留阶数为1的节点:
G = nx.from_pandas_edgelist(df, source='Name', target='Includes')
[nx.shortest_path(G, 'Account', node) for node, degree in G.degree() if degree==1]
[['Account', 'ProductAccount', 'CardAccount', 'Plastic'],
['Account', 'ProductAccount', 'CardAccount', 'Token', 'TokenVault'],
['Account', 'SavingsAccount']]
要直观地了解正在解决的图形问题,请执行以下操作:
pos = nx.spring_layout(G, scale=20)
nx.draw(G, pos, node_color='lightblue', node_size=500, with_labels=True)
正如我们所看到的,通过知道要寻找的源和目标,通过使用nx.shortest_path
我们可以获得Account
和获得的目标之间的路径令人惊讶,我想了十分钟就放弃了。对于这类问题,有没有一个特定的名字可以让我读下去?如果有帮助的话,你可以读下去。答案中还有一个关于最短路径的链接@datanearrow,我想这就是我要找的。是否可以将此代码配置为处理多个根?例如,如果我的根目录中除了“Account”之外还有其他内容。Yes@njrob您可以扩展列表理解以检查多个根节点