小能豆

对列进行排序,使一列的值位于另一列之后

py

我有一个大型数据集,它代表了公司的层次结构树。举个例子,我可能有以下内容:

Child                 Parent
273500                273500
20574624              273500
2202652               1879450
19933526              1879450
18000796              18352628
18352628              19770000
1359996               20574624
1879450               20574624
18441258              20574624
20637582              20574624
20840426              20574624
20844632              20574624
20934910              20574624
20965442              20574624
21193122              20574624
21194666              21193122
19770000              20574624
19681810              18352628
19931554              20574624
18382902              1879450
19780666              1879450
20631784              20574624

可以看到,第一行是父节点。

我想要做的是,对数据进行排序,使其实际上代表一个层次结构,从顶部开始,一直到层次结构的底部。我想要这样做的原因是,我想计算树的高度。为此,首先我需要构造树。我已经知道如何使用 构造树treelib package。我现在的问题是,如果我有一个由数千行组成的大型数据集,我该如何对数据进行排序,以便能够构建一棵树。

我已经尝试过使用 pandas 中的 .sort_values 根据 Child 列中的值对 Parent 列进行排序。但是,这并没有按照我想要的方式工作。我还尝试使用 group by 函数执行此操作,并以某种方式根据以下问题为行赋予一定的排名:pandas 根据另一列中的值对一列进行排序

这对于大型数据集不起作用。

以下是我想要得到的结果。

Child         Parent
273500        273500   # The first row is the parent row
20574624      273500   # I want all children that belong to this parent node
1879450       20574624 #  
18441258      20574624
19770000      20574624
19931554      20574624
20631784      20574624
20637582      20574624
20840426      20574624
20844632      20574624
20934910      20574624
20965442      20574624
21193122      20574624
2202652       1879450 # Now, I want all the children that belong to 1879450
18382902      1879450 # and so on
19780666      1879450
19933526      1879450
18352628      19770000
18000796      18352628
19681810      18352628
1359996       20574624
21194666      21193122

对于如此小的数据集,可以很容易地手动排序。但对于包含数千行的大型数据集,这可能有点麻烦。


阅读 17

收藏
2025-01-09

共1个答案

小能豆

定义以下函数:

def getDescendants(curr, par, level):
    res = [[curr, par, level]]
    children = df.query('Parent == @curr')
    for n in children.Child:
        if n != par:
            deeper = getDescendants(n, curr, level + 1)
            if len(deeper) > 0:
                res.extend(deeper)
    return res

然后获取“所有父母的父母”的 id(从第 0 行开始):

hd = df.iloc[0, 0]

并调用上述函数:

pd.DataFrame(getDescendants(hd, hd, 1), columns=['Child', 'Parent', 'Level'])

此功能的作用不止于此。它还能给出每个人在层级结构中的级别。

查找“所有父母的父母”的替代方法

如果“所有父母的父母”可能位于任意行(不一定在第一行),则需要采用另一种方法。

假设源 DataFrame 包含单个层次树,则根节点可以读作:hd = df.query('Parent == Child').iloc[0,0]。然后按上述方式生成层次树。

如果有多个层次树,则:

  • df.query('Parent == Child').iloc[0]获取一系列根”ID。
  • 您必须为此Series中的每个元素编写一个循环, 对当前id调用getDescendants(id, id, 1)并收集结果(例如作为列表的元素)。
  • 将它们连接起来(垂直)。
2025-01-09