簡體   English   中英

pandas dataframe中的遞歸function

[英]Recursive function in pandas dataframe

我有以下 dataframe 創建者

import pandas as pd    
df = pd.DataFrame({'parent': ['AC1', 'AC2', 'AC3', 'AC1', 'AC11', 'AC5', 'AC5', 'AC6', 'AC8', 'AC9'],
                   'child': ['AC2', 'AC3', 'AC4', 'AC11', 'AC12', 'AC2', 'AC6', 'AC7', 'AC9', 'AC10']})

輸出以下內容:

    parent  child
0   AC1     AC2
1   AC2     AC3
2   AC3     AC4
3   AC1     AC11
4   AC11    AC12
5   AC5     AC2
6   AC5     AC6
7   AC6     AC7
8   AC8     AC9
9   AC9     AC10

我想創建一個結果 dataframe ,其中每個父級(意味着它不存在於子列中)與最后一個子級一起列出。

df_result = pd.DataFrame({'parent': ['AC1', 'AC1', 'AC5', 'AC5', 'AC8', 'AC2'],
                     'child': ['AC4', 'AC12', 'AC4', 'AC7', 'AC10', 'AC4']})
    parent  child
0   AC1     AC4
1   AC1     AC12
2   AC5     AC4
3   AC5     AC7
4   AC8     AC10
5   AC2     AC4

我已經開始了以下 function 但我不確定如何完成它。

def get_child(df):
result = {}
if df['parent'] not in df['child']:
    return result[df['parent']]

這是一種樹結構,一種特殊類型的圖。 數據框不是表示樹的特別方便的方式; 我建議您切換到networkx或其他一些基於圖形的 package。 然后查找如何進行簡單的路徑遍歷; 您將在圖表 package 文檔中找到直接支持。

如果你堅持自己做——這是一個合理的編程練習——你只需要這樣的偽代碼

for each parent not in "child" column:
    here = parent
    while here in parent column:
        here = here["child"]

    record (parent, here) pair

雖然您預期的 output 似乎與您的描述有些不一致(AC2 似乎不應該被視為父節點,因為它不是源節點),但我非常有信心您想要從每個源節點運行遍歷以定位它的所有葉子。 在 dataframe 中這樣做並不方便,因此我們可以使用df.values並創建一個鄰接列表字典來表示圖形。 我假設圖中沒有循環。

import pandas as pd
from collections import defaultdict

def find_leaves(graph, src):
    if src in graph:
        for neighbor in graph[src]:
            yield from find_leaves(graph, neighbor)
    else:
        yield src

def pair_sources_to_leaves(df):
    graph = defaultdict(list)
    children = set()

    for parent, child in df.values:
        graph[parent].append(child)
        children.add(child)

    leaves = [[x, list(find_leaves(graph, x))] 
               for x in graph if x not in children]
    return (pd.DataFrame(leaves, columns=df.columns)
              .explode(df.columns[-1])
              .reset_index(drop=True))

if __name__ == "__main__":
    df = pd.DataFrame({
        "parent": ["AC1", "AC2", "AC3", "AC1", "AC11", 
                   "AC5", "AC5", "AC6", "AC8", "AC9"],
        "child": ["AC2", "AC3", "AC4", "AC11", "AC12", 
                  "AC2", "AC6", "AC7", "AC9", "AC10"]
    })
    print(pair_sources_to_leaves(df))

Output:

  parent child
0    AC1   AC4
1    AC1  AC12
2    AC5   AC4
3    AC5   AC7
4    AC8  AC10

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM