Numpy, 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)