【问题标题】:Converting list of pairwise comparisons to hierarchical representation (columns) using pandas Python使用 pandas Python 将成对比较列表转换为分层表示(列)
【发布时间】:2023-03-14 20:45:01
【问题描述】:

我有一个如下形式的数据集(大约 8000 行)

Employee ID | Manager ID
a | b
c | b
b | e
d | e
e | f

我想将其转换为一个表格,其中显示最低层级的员工和“最高”层级的所有经理之间的整个“链接”,即:

Employee ID | Manager ID 1 | Manager ID 2 | Manager ID 3
a | b | e | f
c | b | e | f
d | e | f

在 Python 中使用 pandas 进行计算的最有效方法是什么?

【问题讨论】:

    标签: python pandas data-structures pairwise


    【解决方案1】:

    这更多地与图和树理论有关。 Pandas 并不专注于这个领域。对于这种事情,networkx比较合适。我提出了一个使用networkx的解决方案。处理前需要安装或pipnetworkx

    从您的数据框中构造一个DiGraph。获取图表的leaves 列表。将列表推导与shortest_path 一起使用以获取从每个rootleaf 的节点列表

    import networkx as nx
    
    G = nx.from_pandas_edgelist(df, 'Employee ID', 'Manager ID', create_using=nx.DiGraph)
    leaves = [node for node in G if G.out_degree(node)==0]
    data   = [nx.shortest_path(G, node, leaf) for node in G if G.in_degree(node)==0 
                                                   for leaf in leaves]
    manager_cols = [f'Manager ID {i}' for i in range(1, df['Manager ID'].nunique()+1)]
    
    df_final = pd.DataFrame(data, columns=['Employee ID', *manager_cols])
    
    Out[371]:
      Employee ID Manager ID 1 Manager ID 2 Manager ID 3
    0           a            b            e            f
    1           c            b            e            f
    2           d            e            f         None
    

    【讨论】:

    • 很好的答案。但假设有 2 个线路管理器(即不止一条最短路径),这两种变体如何在最终输出中作为单独的行返回?
    【解决方案2】:

    这是numpy 的解决方案,而不是pandas 的解决方案,但它可能对您有所帮助:

    employee = np.array(['a', 'c', 'b', 'd', 'e', 'f'])  # Add 'f' as employee 
    manager = np.array(['b', 'b', 'e', 'e', 'f', 'f'])   # being his own manager
    

    获取每个员工的经理编号(sorry):

    manager_idx = np.array([np.where(employee == mng)[0] for mng in manager]).ravel()
    

    循环直到你在层次结构的末尾

    manager_idx_list = [manager_idx]
    while True:
        new_manger_idx = manager_idx_list[-1][manager_idx]
        if all(new_manger_idx == manager_idx_list[-1]):
            break
        else:
            manager_idx_list.append(new_manger_idx)
    
    
    manager_list = np.array([employee[mng_idx] for mng_idx in manager_idx_list]).T
    # 'a': [['b' 'e' 'f']
    # 'c':  ['b' 'e' 'f']
    # 'b':  ['e' 'f' 'f']
    # 'd':  ['e' 'f' 'f']
    # 'e':  ['f' 'f' 'f']
    # 'f':  ['f' 'f' 'f']]
    

    【讨论】:

      猜你喜欢
      • 2020-10-07
      • 2020-12-02
      • 2019-08-04
      • 2010-12-16
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      相关资源
      最近更新 更多