【问题标题】:How to sort Pandas Dataframe based on Parent/Child IDs?如何根据父/子 ID 对 Pandas Dataframe 进行排序?
【发布时间】:2021-03-21 12:26:09
【问题描述】:

我有一个事件日志数据框,其中包含一个带有前一个事件 ID 的列,但它们不是按顺序排列的,我想这样做。如果我们采用以下事件名称、ID 和先前事件 ID 的数据帧并将其打乱,我们会得到:

  import pandas as pd
  import numpy as np
  df = pd.DataFrame(
      {
          'Event_name': ['First', 'Second', 'Third', 'Fourth', 'Fifth', 'Sixth', 'Seventh', 'Eigth', 'Ninth', 'Tenth'],
          'Event_Ids': ['QXT364', 'YKD306', 'GJJ60', 'RSK547', 'GNN259', 'DKW368', 'OAN385', 'PGF213', 'NGJ285', 'OLG594'],
          'Previous_Event_Ids': [np.nan,'QXT364', 'YKD306', 'GJJ60', 'RSK547', 'GNN259', 'DKW368', 'OAN385', 'PGF213', 'NGJ285']
    }
  )
df = df.sample(frac=1).reset_index(drop=True)
print(df)

它输出:

     Event_name Event_Ids Previous_Event_Ids
0     Fourth    RSK547              GJJ60
1      Eigth    PGF213             OAN385
2      First    QXT364                NaN
3      Third     GJJ60             YKD306
4      Fifth    GNN259             RSK547
5      Sixth    DKW368             GNN259
6    Seventh    OAN385             DKW368
7      Ninth    NGJ285             PGF213
8     Second    YKD306             QXT364
9      Tenth    OLG594             NGJ285

可以使用什么代码对其进行排序以使 DataFrame 以这样的方式结束?

  Event_name Event_Ids Previous_Event_Ids
0      First    QXT364                NaN
1     Second    YKD306             QXT364
2      Third     GJJ60             YKD306
3     Fourth    RSK547              GJJ60
4      Fifth    GNN259             RSK547
5      Sixth    DKW368             GNN259
6    Seventh    OAN385             DKW368
7      Eigth    PGF213             OAN385
8      Ninth    NGJ285             PGF213
9      Tenth    OLG594             NGJ285

【问题讨论】:

    标签: python pandas dataframe sorting indexing


    【解决方案1】:

    您需要有一个dict 将字符串值映射到int,然后按整数值排序:

    In [301]: vars_map = {'First': 1, 'Second': 2, 'Third': 3, 'Fourth':4, 'Fifth':5, 'Sixth':6, 'Seventh': 7, 'Eigth':8, 'Ninth':9, 'Tenth':10}
    
    In [305]: df1 = df.assign(vals=df.Event_name.map(vars_map)).sort_values('vals').drop('vals', 1)
    
    In [306]: df1
    Out[306]: 
      Event_name Event_Ids Previous_Event_Ids
    1      First    QXT364                NaN
    3     Second    YKD306             QXT364
    5      Third     GJJ60             YKD306
    7     Fourth    RSK547              GJJ60
    9      Fifth    GNN259             RSK547
    2      Sixth    DKW368             GNN259
    8    Seventh    OAN385             DKW368
    0      Eigth    PGF213             OAN385
    6      Ninth    NGJ285             PGF213
    4      Tenth    OLG594             NGJ285
    

    【讨论】:

    • 没有dict 地图有没有办法做到这一点?例如,如果我们不知道First 是第一个值,Second 是第二个值,以此类推
    • 我猜dict 在这里是必不可少的。否则没有办法告诉 Python 以你想要的方式对其进行排序。本质上,First 可以是任何小于Second 的值,依此类推。
    • 我们是否可以使用for 循环来查找匹配的Event_IdsPrevious_Event_Ids 对,然后使用顶部的NaN 进行排序?
    • 实际上似乎可以..你只需要知道第一个..并且nan是标识符
    【解决方案2】:

    我可以通过以下代码解决这个问题:

    # Step 1: Initialize the dictionary
    var_map = dict.fromkeys(df.index.values)
    
    # Step 2: Find our start value, NaN
    nanLoc,_ = np.where(df.isna())
    
    # Step 3: Put NaN in the first slot of the dictionary
    var_map[0] = df.loc[nanLoc].values.tolist()[0]
    
    # Step 4: Iterate through the dataframe
    for x in df.index.values[:-1]:
        key = var_map[x][1]
        var_map[x+1] = df.loc[df['Previous_Event_Ids'] == key].values.tolist()[0]
    
    #Step 5: Turn the dictionary into a DataFrame
    df2 = pd.DataFrame.from_dict(var_map, orient='index', columns=['Event_name', 'Event_Ids', 'Previous_Event_Ids'])
    print(df2)
    

    【讨论】:

      猜你喜欢
      • 2021-03-21
      • 2020-10-27
      • 2017-09-14
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多