Переход от cumsum к нормальным значениям

Есть столбец, в котором данные представляют собой кумулятивную сумму. Суммы считаются в рамках одного года. После перехода к новому году сумма обновляется. При этом еще есть столбец с фильтром. Кумулятивная сумма считается для каждого объекта из столбца с фильтром отдельно. Пример выглядит следующим образом:

╔════════════╦════════╦═══════════╗
║    Дата    ║ Фильтр ║ Значения  ║
╠════════════╬════════╬═══════════╣
║ 01.01.2013 ║ первый ║ 1         ║
║ 01.01.2013 ║ второй ║ 2         ║
║ 01.02.2013 ║ первый ║ 2         ║
║ 01.02.2013 ║ второй ║ 4         ║
║ 01.03.2013 ║ первый ║ 3         ║
║ 01.03.2013 ║ второй ║ 6         ║
║ ...        ║ ...    ║ ...       ║
║ 01.01.2014 ║ первый ║ 1         ║
║ 01.01.2014 ║ второй ║ 2         ║
║ 01.02.2014 ║ первый ║ 2         ║
║ 01.02.2014 ║ второй ║ 4         ║
║ 01.03.2014 ║ первый ║ 3         ║
║ 01.03.2014 ║ второй ║ 6         ║
╚════════════╩════════╩═══════════╝

Необхдимо уйти от кумулятивных сумм к обычным значениям, чтобы в итоге получилась таблица вида:

╔════════════╦════════╦═══════════╗
║    Дата    ║ Фильтр ║ Значения  ║
╠════════════╬════════╬═══════════╣
║ 01.01.2013 ║ первый ║ 1         ║
║ 01.01.2013 ║ второй ║ 2         ║
║ 01.02.2013 ║ первый ║ 1         ║
║ 01.02.2013 ║ второй ║ 2         ║
║ 01.03.2013 ║ первый ║ 1         ║
║ 01.03.2013 ║ второй ║ 2         ║
║ ...        ║ ...    ║ ...       ║
║ 01.01.2014 ║ первый ║ 1         ║
║ 01.01.2014 ║ второй ║ 2         ║
║ 01.02.2014 ║ первый ║ 1         ║
║ 01.02.2014 ║ второй ║ 2         ║
║ 01.03.2014 ║ первый ║ 1         ║
║ 01.03.2014 ║ второй ║ 2         ║
╚════════════╩════════╩═══════════╝

Ответы (1 шт):

Автор решения: strawdog

Допустим у вас есть датафрейм:

import pandas as pd

df = pd.DataFrame({"A":[1,1,1,1,1,2,2,2,2,2], "B":[1,2,3,4,5,11,22,33,44,55]})
   A   B
0  1   1
1  1   2
2  1   3
3  1   4
4  1   5
5  2  11
6  2  22
7  2  33
8  2  44
9  2  55

вы где-то вычислили по нему кумулятивную сумму в колонке B, сгруппировав по A:

   A   B  c-sum
0  1   1      1
1  1   2      3
2  1   3      6
3  1   4     10
4  1   5     15
5  2  11     11
6  2  22     33
7  2  33     66
8  2  44    110
9  2  55    165

чтобы получить исходные значения, достаточно сделать следующее:

df["orig"] = df.groupby("A")["c-sum"].diff().fillna(df["c-sum"])

тогда в колонке orig у вас будут исходные значения:

   A   B  c-sum  orig
0  1   1      1   1.0
1  1   2      3   2.0
2  1   3      6   3.0
3  1   4     10   4.0
4  1   5     15   5.0
5  2  11     11  11.0
6  2  22     33  22.0
7  2  33     66  33.0
8  2  44    110  44.0
9  2  55    165  55.0

тип данных в новой колонке вы тоже можете легко изменить:

df["orig"] = df.groupby("A")["c-sum"].diff().fillna(df["c-sum"]).astype("int")

получим:

   A   B  c-sum  orig
0  1   1      1     1
1  1   2      3     2
2  1   3      6     3
3  1   4     10     4
4  1   5     15     5
5  2  11     11    11
6  2  22     33    22
7  2  33     66    33
8  2  44    110    44
9  2  55    165    55
→ Ссылка