Панды: Начиная со второго ряда.вычесть из предыдущего ряда и использовать его в качестве значения для следующего вычитания - PullRequest
0 голосов
/ 12 сентября 2018

Контекст

Мне нужно закодировать алгоритм с помощью 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 голосов
/ 12 сентября 2018

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)
0 голосов
/ 12 сентября 2018

Это должно работать:

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)
0 голосов
/ 12 сентября 2018

Трудно сказать, есть ли способ панды сделать это, поэтому я задавал этот вопрос пару месяцев назад. И ниже мое решение.

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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...