【问题标题】:Flattening a Parent Child relationship with Pandas用 Pandas 扁平化父子关系
【发布时间】:2020-04-02 13:27:17
【问题描述】:

我是 pandas 的新手,正在寻找一种使用 pandas 或 python 来扁平化多级父子关系的方法。我有一个包含如下数据的 csv 文件。

对于每个孩子,我想从 parent 遍历到 child 。任何形式的帮助表示赞赏。

输入

--------------------
Child,Parent,Country
--------------------
A,TOP LEVEL,GERMANY

B,A,USA

C,B,JAPAN

D,TOP LEVEL,INDIA

E,D,CHINA

输出

--------------------
HIERARCHY,COUNTRY
--------------------
A,GERMANY

A.B,USA

A.B.C,JAPAN

D,INDIA

D.E,CHINA

【问题讨论】:

  • 为什么不直接在输出中直接使用国家关系的父子关系,而不是通过这些其他映射来缓解它?
  • 第三行不应该是C,B,A,JAPAN吗?

标签: python pandas


【解决方案1】:

这可以使用networkx 和有向图来完成,以防您的原始数据帧中的内容不一定正确排序。首先,我们需要修复 DataFrame,使 TOP LEVEL 不是父级并使用国家/地区。

import pandas as pd
import networkx as nx

df['True_Parent'] = df['Parent'].mask(df['Parent'].eq('TOP LEVEL')).fillna(df['Country'])
#  Child     Parent  Country True_Parent
#0     A  TOP LEVEL  GERMANY     GERMANY
#1     B          A      USA           A
#2     C          B    JAPAN           B
#3     D  TOP LEVEL    INDIA       INDIA
#4     E          D    CHINA           D

现在创建有向图

G = nx.from_pandas_edgelist(df, source='True_Parent', target='Child', 
                            create_using=nx.DiGraph())

我们想要的是所有的前辈,递归:

def all_preds(G, target):
    preds=[target]
    for p in list(G.predecessors(target)):
        preds += all_preds(G, p)
    return preds

df['Hierarchy'] = ['.'.join(all_preds(G, country)[:-1][::-1]) for country in df['Child'].unique()]
#  Child     Parent  Country True_Parent Hierarchy
#0     A  TOP LEVEL  GERMANY     GERMANY         A
#1     B          A      USA           A       A.B
#2     C          B    JAPAN           B     A.B.C
#3     D  TOP LEVEL    INDIA       INDIA         D
#4     E          D    CHINA           D       D.E

这样的关系有点奇怪。在第一组中,您有 TOP LEVEL、A、B、C,但只有 3 个独特的国家/地区。如果您想创建更简洁的父子映射,我们可以在制作图表之前完成:

(df.groupby(df.Parent.eq('TOP LEVEL').cumsum())
   .apply(lambda gp: gp.replace(gp.set_index('Child').Country.to_dict()))
   .query('Parent != "TOP LEVEL"')[['Child', 'Parent']])

#   Child   Parent
#1    USA  GERMANY
#2  JAPAN      USA
#4  CHINA    INDIA

【讨论】:

  • 谢谢@ALollz。我只需要层次结构以及相应的 Country 值。但我可以删除 True_Parent 以获得所需的输出。
猜你喜欢
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
  • 2021-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多