【问题标题】:Using pandas to group hierarchical data [Parent->Child] tree efficiently使用 pandas 对分层数据 [Parent->Child] 树进行有效分组
【发布时间】:2019-10-25 21:37:51
【问题描述】:

我有一个看起来像这样的数据框,每个都有一个祖先 -> 父级 -> 子级关系。 我想通过追溯祖先并递归查找孩子来对数据进行分组。

No  Name    Ancestor MyID Parent_Id
1   Tom       191     211 111
2   Galie     191     209 111
3   Remo      434     200 101
4   Carmen    454     212 121
5   Alfred    191     111 191
6   Marvela   191     101 111
7   Armin     322     234 101
8   Boris     989     454 109
9   Katya     921     109 323
10  Adam      191     191 Null

例如:

Ancestory: 191 将导致 heiarchy 的顺序:

(祖父母 -> 父母 -> 孩子)。

1  Adam      191     191 Null
2   Alfred    191     111 191
3   Tom       191     211 111
4   Galie     191     209 111
5   Marvela   191     101 111

我的方法(不使用 pandas)是首先在列 (Ancestor) 中找到唯一的祖先,然后使用 for 循环遍历列表中的每个唯一项,并递归地遍历每个项以找到子项。 这工作得很好,但数据帧有大约 100K 个整体,并且 for 循环变得越来越昂贵。

什么是使用 pandas 来解决这个问题而不必使用昂贵的迭代 for 循环的最佳方法?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    可能是您想要的结果:

    df_source = pd.read_excel('data8.xlsx', index_col = 'No')
    df_source['Parent_Id'] = pd.to_numeric(df_source['Parent_Id'], errors = 'coerce').fillna(-1)
    
    df_p = df_source[df_source['Parent_Id'] == -1]
    df_p.columns = pd.MultiIndex.from_product([[1],df_source.columns])
    
    df = df_source.copy()
    df.columns = pd.MultiIndex.from_product([[2],df_source.columns])
    
    step = 2
    while True:
    
        df_p = df_p.merge(df, how = 'left', left_on = [(step-1,'MyID')], right_on = [(step,'Parent_Id')])
    
        step+=1
        df = df_source.copy()
        df.columns = pd.MultiIndex.from_product([[step],df_source.columns])
        if len(set(df_p[(step-1,'MyID')]).intersection(set(df[(step,'Parent_Id')]))) == 0: break
    
    
    Out[1]:
    
        1                               2                                       3                                       4
        Name Ancestor MyID  Parent_Id   Name    Ancestor    MyID    Parent_Id   Name    Ancestor    MyID    Parent_Id   Name    Ancestor    MyID    Parent_Id
    0   Adam    191   191     -1.0      Alfred     191      111      191.0      Tom     191         211       111.0     NaN        NaN      NaN       NaN
    1   Adam    191   191     -1.0      Alfred     191      111      191.0      Galie   191         209       111.0     NaN        NaN      NaN       NaN
    2   Adam    191   191     -1.0      Alfred     191      111      191.0      Marvela 191         101       111.0     Remo       434.0    200.0    101.0
    3   Adam    191   191     -1.0      Alfred     191      111      191.0      Marvela 191         101       111.0     Armin      322.0    234.0    101.0
    

    按步骤:

    Out[1]:
    
            1
        Name    Ancestor    MyID    Parent_Id
    No              
    10  Adam       191      191        -1.0
    
    
    Out[2]:
    
            1                                   2
        Name    Ancestor    MyID    Parent_Id   Name    Ancestor    MyID    Parent_Id
    0   Adam       191      191       -1.0      Alfred     191       111    191.0
    
    
    Out[3]:
    
        1                                       2                                       3
        Name    Ancestor    MyID    Parent_Id   Name    Ancestor    MyID    Parent_Id   Name    Ancestor    MyID    Parent_Id
    0   Adam       191      191      -1.0       Alfred     191      111     191.0       Tom      191        211        111.0
    1   Adam       191      191      -1.0       Alfred     191      111     191.0       Galie    191        209        111.0
    2   Adam       191      191      -1.0       Alfred     191      111     191.0       Marvela  191        101        111.0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多