代码之家  ›  专栏  ›  技术社区  ›  darkpool

基于多个条件筛选行

  •  0
  • darkpool  · 技术社区  · 5 年前

    我有以下数据帧:

    name        date_one        date_two
    -----------------------------------------
    sue
    sue
    john    
    john        13-06-2019
    sally       23-04-2019
    sally       23-04-2019      25-04-2019
    bob         18-05-2019      14-06-2019
    bob         18-05-2019      17-06-2019
    

    数据中包含重复数据 name 排。我需要根据以下内容(按优先顺序)过滤数据:

    1. 每人 名称 ,用最新的 date_two .如果 名称 没有任何具有值的行 二号约会 ,转至步骤2
    2. 每人 名称 ,用最新的 date_one .如果 名称 没有任何具有值的行 第一次约会 ,转至步骤3
    3. 这些 names 没有任何行具有 第一次约会 二号约会 所以只需保持第一排就可以了 名称

    上述数据帧将被过滤为:

    name        date_one        date_two
    -----------------------------------------
    sue
    john        13-06-2019
    sally       23-04-2019      25-04-2019
    bob         18-05-2019      17-06-2019
    

    这不需要以最高效的方式完成。数据帧只有几千行,只需要执行一次。如果需要分多个(缓慢的)步骤来完成,那很好。

    0 回复  |  直到 5 年前
        1
  •  1
  •   jezrael    5 年前

    使用 DataFrameGroupBy.idxmax 按最大值对行进行分组,然后按 Series.isin 最后,通过价值将它们结合在一起 concat :

    df['date_one'] = pd.to_datetime(df['date_one'], dayfirst=True)
    df['date_two'] = pd.to_datetime(df['date_two'], dayfirst=True)
    
    #rule1
    df1 = df.loc[df.groupby('name')['date_two'].idxmax().dropna()]
    
    #rule2
    df2 = df.loc[df.groupby('name')['date_one'].idxmax().dropna()]
    df2 = df2[~df2['name'].isin(df1['name'])]
    
    #rule3
    df3 = df[~df['name'].isin(df1['name'].append(df2['name']))].drop_duplicates('name')
    
    df = pd.concat([df1, df2, df3]).sort_index()
    print (df)
        name   date_one   date_two
    0    sue        NaT        NaT
    3   john 2019-06-13        NaT
    5  sally 2019-04-23 2019-04-25
    7    bob 2019-05-18 2019-06-17