【问题标题】:calculate a value in a row based on before and after rows in pandas根据熊猫中的前后行计算一行中的值
【发布时间】:2021-06-02 11:18:49
【问题描述】:

我有以下数据框:

 p l w s_w  v
 1 1 1  1   2
 1 1 2  1   2
 1 1 3  0   5
 1 1 4  1   5
 1 1 5  1   5
 2 1 1  1   1
 2 1 2  0   2
 2 1 3  0   3
 2 1 4  0   4
 2 1 5  1   5
 2 1 6  1   4

我想要一个新专栏 如果 s_w 的值为 1,则在每一行中, 它的值是前两行中的 sum(v)(不一定是连续的),其中 s_w==1 和 sum(v) 用于随后的两行(不一定是连续的),同样是 s_w==1 所以 sum(v) + sum(v)。

我对中间的任何数量的零都不感兴趣

所以结果数据框看起来像这样:

 p l w s_w  v  c_s
 1 1 1  1   2   Null
 1 1 2  1   2   Null
 1 1 3  0   5   Null
 1 1 4  1   5   10
 1 1 5  1   5   13
 2 1 1  1   1   19
 2 1 2  0   2  Null
 2 1 3  0   3  Null
 2 1 4  0   4  Null
 2 1 5  1   5  Null
 2 1 6  1   4  Null

最后两行的值将为 Null,因为它们之后没有两个 1(n 换句话说,只有在前后行中有两个 1 时才前后求和(不一定连续,否则为 Null)

对原始问题的新编辑:

对于每组 P,l 如果只有检查列中的值为 1,则在 s_w 列和前两行的 sum(v) 中找到上述模式,其中 s_w==1 (不一定是连续的)并且也求和(v) 以下两行,其中 s_w==1(不一定连续)

 p l w s_w check v
 1 1 1  1     0   2
 1 1 2  1     0   2
 1 1 3  0     0   5
 1 1 4  1     0   5
 1 1 5  1     1   5
 2 1 1  1     0   1
 2 1 2  0     0   2
 2 1 3  0     0   3
 2 1 4  0     0   4
 2 1 5  1     0   5
 2 1 6  1     0   4

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:

    想法是使用1 过滤行并使用带有移位值的rolling sum 进行正确对齐:

    s = df.loc[df['s_w'].eq(1), 'v']
    
    df['c_s'] = s.rolling(2).sum().shift().add(s.iloc[::-1].rolling(2).sum().shift())
    print (df)
        p  l  w  s_w  v   c_s
    0   1  1  1    1  2   NaN
    1   1  1  2    1  2   NaN
    2   1  1  3    0  5   NaN
    3   1  1  4    1  5  10.0
    4   1  1  5    1  5  13.0
    5   2  1  1    1  1  19.0
    6   2  1  2    0  2   NaN
    7   2  1  3    0  3   NaN
    8   2  1  4    0  4   NaN
    9   2  1  5    1  5   NaN
    10  2  1  6    1  4   NaN
    

    另一个想法:

    df['c_s'] = s.shift(-1).add(s.shift(-2)).add(s.shift(2)).add(s.shift(1))
    

    编辑:

    每组解决方案:

    s = df[df['s_w'].eq(1)]
    
    f = lambda x: x.rolling(2).sum().shift()
    df['c_s'] = s.groupby(['p','l'])['v'].apply(f).add(s.iloc[::-1].groupby(['p','l'])['v'].apply(f))
    

    g = df[df['s_w'].eq(1)].groupby(['p','l'])['v']
    df['c_s'] = g.shift(-1).add(g.shift(-2)).add(g.shift(2)).add(g.shift(1))
    

    【讨论】:

    • 对不起,我在结果数据框中犯了一个错误,我想对之前和之后进行 sum(v),但在结果数据框中,我只是计算了前两行的总和,我将对其进行编辑,您能否相应地编辑答案?
    • 太棒了!谢谢,我怎样才能改变它以单独应用于每个 P,l 组?所以只在 P,l 组(组合)中查找前后的行
    • @chessosapiens - 添加了一些想法,你能测试一下吗?
    • 组解决方案在示例 df 上运行良好,应该为所有行返回 nan。
    • 我们如何改变答案,让行前和行后都乘以权重数组,例如 weight =np.array([0.1,0.5]) 然后将它们加在一起?
    猜你喜欢
    • 2017-08-15
    • 2020-11-12
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多