【问题标题】:Python - Grouping and Assigning Exception RulesPython - 分组和分配异常规则
【发布时间】:2020-11-18 08:41:28
【问题描述】:

如果最接近 0 的负差异是位置 86 作为组 1,我想首先按列表分组,如果最接近 0 的负差异是位置 90,我想分配组 2。并且如果位置 86 和 90 是最近的,那么组 3 将是。运行此组后,我将重新运行代码,并且在未分配组的任何地方,它从第 4 组开始分配,以免覆盖以前的组分配。

groupby 是根据 ID、Location 和最接近 Anchor 列发生的。

请注意,在下面的示例中,我们跳过位置 66 作为例外,我将使用 df['diff'].where(df['diff'].le(0)&df['Anchor Date'].ne('Y')&df['Location'].ne(66))

输入:

ID  Location Anchor Date       Diff
111 86       N      5/2/2020  -1
111 87       Y      5/3/2020   0
111 90       N      5/4/2020  -2
111 90       Y      5/6/2020   0
123 86       N      1/4/2020  -1
123 90       N      1/4/2020  -1
123 91       Y      1/5/2020   0
456 64       N      2/3/2020  -2
456 66       N      2/4/2020  -1
456 91       Y      2/5/2020   0

输出:

ID  Location Anchor Date       Diff  Group
111 86       N      5/2/2020  -1     1
111 87       Y      5/3/2020   0
111 90       N      5/4/2020  -2     2
111 90       Y      5/6/2020   0
123 86       N      1/4/2020  -1     3
123 90       N      1/4/2020  -1     3
123 91       Y      1/5/2020   0     
456 64       N      2/3/2020  -2     4
456 66       N      2/4/2020  -1     
456 91       Y      2/5/2020   0

【问题讨论】:

    标签: python pandas datetime pandas-groupby


    【解决方案1】:

    在您的异常规则中,同时具有 86 和 90 的规则会增加代码的复杂性,因为需要为由两个位置组成的这个组获取一个值。一般来说,如果相同的差异更难,您想要捕获多个位置。这是一种方法。创建具有不同组值和掩码的系列

    #catch each group per ID and up until a 0
    gr = (df['ID'].ne(df['ID']).shift()|df['Anchor'].shift().eq('Y')).cumsum()
    # where the diff per group is equal to the last value possible before anchor
    mask_last = (df['Diff'].where(df['Diff'].le(0)&df['Anchor'].ne('Y')&df['Location'].ne(66))
                           .groupby(gr).transform('last')
                           .eq(df['Diff']))
    # need this info to create unique fake Location value, especially if several
    loc_max = df['Location'].max()+1
    #create groups based on Location value
    gr2 = (df['Location'].where(mask_last).groupby(gr)
                         .transform(lambda x:(x.dropna().sort_values()
                                              *loc_max**np.arange(len(x.dropna()))).sum()))
    

    现在您可以创建组了:

    #now create the column group
    d_exception = {86:1, 90:2, 86 + 90*loc_max:3} #you can add more
    df['group'] = ''
    #exception
    for key, val in d_exception.items():
        df.loc[mask_last&gr2.eq(key), 'group'] = val
    #the rest of the groups
    idx = df.index[mask_last&~gr2.isin(d_exception.keys())]
    df.loc[idx, 'group'] = pd.factorize(df.loc[idx, 'Location'])[0]+len(d_exception)+1
    print (df)
        ID  Location Anchor      Date  Diff group
    0  111        86      N  5/2/2020    -1     1
    1  111        87      Y  5/3/2020     0      
    2  111        90      N  5/4/2020    -2     2
    3  111        90      Y  5/6/2020     0      
    4  123        86      N  1/4/2020    -1     3
    5  123        90      N  1/4/2020    -1     3
    6  123        91      Y  1/5/2020     0      
    7  456        64      N  2/3/2020    -2     4
    8  456        66      N  2/4/2020    -1      
    9  456        91      Y  2/5/2020     0      
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 2012-01-03
      • 2013-03-04
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      相关资源
      最近更新 更多