Вычитание серии панд из всех элементов другой серии панд с общим идентификатором

У меня есть объекты панды series.groupby, назовите их data. Если я распечатаю элементы, это будет выглядеть так:

<pandas.core.groupby.generic.SeriesGroupBy object at ***>
(1, 0     397.44
    1     12.72
    2     422.40
Name: value, dtype: float64)
(2, 3     398.88
    4     6.48
    5     413.52
Name: value, dtype: float64)
(3, 6     398.40
    7     68.40
    8     18.96
    9     56.64
    10    406.56
Name: value, dtype: float64)
(4, 11    398.64
    12    14.64
    13    413.76
Name: value, dtype: float64)
...

Я хочу создать эквивалентный объект, записи которого представляют собой совокупную сумму каждого подсписка в серии за вычетом первой записи этого списка. Так, например, первый элемент будет выглядеть так:

(1, 0     0         #(= 397.44 - 397.44)
    1     12.72     #(= 397.44 + 12.72 - 397.44)
    2     435.12    #(= 397.44 + 12.72 + 422.40 - 397.44)

Я могу легко получить совокупную сумму, используя apply:

cumulative_sums = data.apply(lambda x: x.cumsum())

но когда я пытаюсь вычесть первый элемент списка интуитивно понятным способом (lambda x: x.cumsum()-x[0]), я получаю KeyError. Как я могу достичь того, что пытаюсь сделать?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Пытаться:

cumulative_sums = data.apply(lambda x: x.cumsum() - x.iat[0])
print(cumulative_sums)

Распечатки:

a  b 
1  0       0.00
   1      12.72
   2     435.12
2  3       0.00
   4       6.48
   5     420.00
3  6       0.00
   7      68.40
   8      87.36
   9     144.00
   10    550.56
Name: value, dtype: float64

Красиво спасибо.

KBriggs 05.07.2024 03:21

Лучше всего избегать apply (это цикл) и использовать cumsum / преобразование, оптимизированное для этой конкретной задачи:

cumulative_sums = data.cumsum()-data.transform('first')

Выход:

0       0.00
1      12.72
2     435.12
3       0.00
4       6.48
5     420.00
6       0.00
7      68.40
8      87.36
9     144.00
10    550.56
11      0.00
12     14.64
13    428.40
Name: value, dtype: float64

Прирост в скорости весьма заметен:

Обратите внимание: если значения в исходном наборе данных отсортированы по группам, вы даже можете избежать groupby. Предполагая, что df введено с group/value в виде столбцов:

cs = df['value'].cumsum()
cumulative_sums = cs-cs.mask(df['group'].duplicated()).ffill()

Вариант с двумя сериями:

cs = series.cumsum()
cumulative_sums = cs-cs.mask(group.duplicated()).ffill()

Что еще быстрее:

Пример ввода для альтернативы:

series = pd.Series([1, 2, 3, 10, 2, 30, 7, 1, 2, 3])
group = pd.Series([0,0,0,1,1,1,1,2,2,2])
df = pd.DataFrame({'group': group, 'value': series})

Впечатляющее ускорение! Для меня это разовая оптимизация не так важна, но это отличный ответ для тех, кто пытается сделать что-то подобное, и я буду иметь это в виду для будущих связанных задач.

KBriggs 05.07.2024 13:00

Другие вопросы по теме