代码之家  ›  专栏  ›  技术社区  ›  Khalil Al Hooti

使用应用于groupby的函数的结果对原始df进行计算

  •  1
  • Khalil Al Hooti  · 技术社区  · 7 年前

    df . 我试着先用这个函数计算每组的平均角度 mean_angle . 然后使用计算出的平均角对每组使用该函数进行另一次计算 fun .

    import pandas as pd
    import numpy as np
    

    生成示例数据

    a = np.array([1,2,3,4]).repeat(4)
    x1 = 90 + np.random.randint(-15, 15, size=a.size//2 - 2 )
    x2 = 270 + np.random.randint(-50, 50, size=a.size//2 + 2 )
    
    b = np.concatenate((x1, x2))
    np.random.shuffle(b) 
    
    df = pd.DataFrame({'a':a, 'b':b})
    

    返回的数据帧打印在下面。

        a   b
    0   1   295
    1   1   78
    2   1   280
    3   1   94
    4   2   308
    5   2   227
    6   2   96
    7   2   299
    8   3   248
    9   3   288
    10  3   81
    11  3   78
    12  4   103
    13  4   265
    14  4   309
    15  4   229
    

    平均角 乐趣

    def mean_angle(deg):
    
        deg = np.deg2rad(deg)
    
        deg = deg[~np.isnan(deg)]
    
        S = np.sum(np.sin(deg))
        C = np.sum(np.cos(deg))
        mu = np.arctan2(S,C)
        mu = np.rad2deg(mu)
    
        if mu <0:
            mu = 360 + mu
    
        return mu
    
    def fun(x, mu):
    
        return  np.where(abs(mu - x) < 45, x, np.where(x+180<360, x+180, x-180))
    

    mu = df.groupby(['a'])['b'].apply(mean_angle)
    
    df2 = df.groupby(['a'])['b'].apply(fun, args = (mu,)) #this function should be element wise
    

    我知道这是完全错误的,但我想不出更好的办法。

    期望的输出是这样的 哪里 mu 每组的平均角度

     a   b   c
    0   1   295 np.where(abs(mu - 295) < 45, 295, np.where(295 +180<360, 295 +180, 295 -180))
    1   1   78 np.where(abs(mu - 78) < 45, 78, np.where(78 +180<360, 78 +180, 78 -180))
    2   1   280 np.where(abs(mu - 280  < 45, 280, np.where(280  +180<360, 280  +180, 280  -180))
    3   1   94                ...
    4   2   308               ...
    5   2   227                .
    6   2   96                 .
    7   2   299                .
    8   3   248                .
    9   3   288                .
    10  3   81                 .
    11  3   78                 .
    12  4   103                .
    13  4   265                .
    14  4   309                .
    15  4   229                .
    

    感谢您的帮助

    1 回复  |  直到 7 年前
        1
  •  1
  •   rahlf23    7 年前

    您不需要第二个函数,只需将必要的列传递给 np.where() . 因此,以相同的方式创建数据帧,而不是修改 mean_angle 函数,我们有以下示例数据帧:

        a    b
    0   1  228
    1   1  291
    2   1   84
    3   1  226
    4   2  266
    5   2  311
    6   2   82
    7   2  274
    8   3   79
    9   3  250
    10  3  222
    11  3   88
    12  4   80
    13  4  291
    14  4  100
    15  4  293
    

    然后创建你的 c mu 值)使用 groupby() transform() ,最后应用 逻辑:

    df['c'] = df.groupby(['a'])['b'].transform(mean_angle)
    df['c'] = np.where(abs(df['c'] - df['b']) < 45, df['b'], np.where(df['b']+180<360, df['b']+180, df['b']-180))
    

    产量:

        a    b    c
    0   1  228  228
    1   1  291  111
    2   1   84  264
    3   1  226  226
    4   2  266  266
    5   2  311  311
    6   2   82  262
    7   2  274  274
    8   3   79  259
    9   3  250   70
    10  3  222   42
    11  3   88  268
    12  4   80  260
    13  4  291  111
    14  4  100  280
    15  4  293  113