熊猫:从第二行开始。从上一行中减去并将其用作下一个减法的值

时间:2018-09-12 13:35:54

标签: python pandas

上下文

我需要使用Pandas编码算法,从第二行开始,从上一行减去列值,并使用结果继续减去下一行,等等。

示例

INPUT:
ID    VALUE
0       1
1       10
2       30
3       45
4       78

OUTPUT (just the result, not the operation itself):
ID    VALUE
0       1
1       9  #(10-1)
2       21 #(30-9)
3       24 #(45-21)
4       54 #(78-24)

我尝试过的

df['VALUE'] = df['VALUE'] - df['VALUE]'.shift() # Doesn't starts with the second row, and use the original dataframe to subtract

df['VALUE'] = df['VALUE'].diff() # Doesn't starts with the second row, and use the original dataframe to subtract

3 个答案:

答案 0 :(得分:8)

脾气暴躁,cumsum带有交替符号

i = np.arange(len(df))
j = np.arange(2)

a = np.where(
    (i[:, None] + j) % 2 == 0, 1, -1
) * df.VALUE.values[:, None]

b = a.cumsum(0)[i, i % 2]

df.assign(VALUE=b)

   ID  VALUE
0   0      1
1   1      9
2   2     21
3   3     24
4   4     54

说明

首先要注意的是

X0 ->                     X0
X1 ->                X1 - X0
X2 ->           X2 - X1 + X0
X3 ->      X3 - X2 + X1 - X0
X4 -> X4 - X3 + X2 - X1 + X0

所以我想将每隔一行乘以负数...但是对于交替行的另一种选择,我需要这样做两次。

我需要生成一个在两个选项的+和-1之间切换的掩码

i = np.arange(len(df))
j = np.arange(2)

m = np.where(
    (i[:, None] + j) % 2 == 0, 1, -1
)

m

array([[ 1, -1],
       [-1,  1],
       [ 1, -1],
       [-1,  1],
       [ 1, -1]])

现在我需要在我的df.VALUE上广播此乘数

a = m * df.VALUE.values[:, None]

a

array([[  1,  -1],
       [-10,  10],
       [ 30, -30],
       [-45,  45],
       [ 78, -78]])

注意图案。现在,我cumsum

a.cumsum(0)

array([[  1,  -1],
       [ -9,   9],
       [ 21, -21],
       [-24,  24],
       [ 54, -54]])

但是我需要正面的...更具体地说,我需要交替的。因此,我用经过修改的arange

b = a.cumsum(0)[i, i % 2]
b

array([ 1,  9, 21, 24, 54])

这就是我最终分配给现有列的内容

df.assign(VALUE=b)

   ID  VALUE
0   0      1
1   1      9
2   2     21
3   3     24
4   4     54

这将产生df的副本,并用VALUE覆盖b列。
要坚持这个答案,请确保重新分配一个新名称,或者根据需要重新命名为df

df_new = df.assign(VALUE=b)

答案 1 :(得分:3)

很难说是否有熊猫这样做的方法,几个月前我问了这个问题。下面是我的解决方案。

l=[]
for x,y in enumerate(df.VALUE):
    if x ==0: 
       l.append(y)
    else : 
       l.append(y-l[x-1])
l
Out[20]: [1, 9, 21, 24, 54]

答案 2 :(得分:1)

这应该有效:

df = pd.DataFrame({"ID": [0, 1, 2, 3, 4], 
                   "VALUE": [1, 10, 30, 45, 78]})
cumsum_with_parity = df.groupby(df.index % 2).VALUE.cumsum()
df["VALUE"] = cumsum_with_parity - cumsum_with_parity.shift().fillna(0)