#pandas #dataframe #iteration #pandas-groupby #vectorization
Вопрос:
У меня есть фрейм данных, и я хотел бы сгруппировать его по значению столбца, а затем выполнить расчет для создания нового столбца. Ниже приведены настроенные данные:
import pandas as pd
df = pd.DataFrame({
'Red' : [1,2,3,4,5,6,7,8,9,10],
'Groups':['A','B','A','A','B','C','B','C','B','C'],
'Blue':[10,20,30,40,50,60,70,80,90,100]
})
df.groupby('Groups').apply(print)
Что я хочу сделать, так это создать столбец «ВСЕГО» в исходном кадре данных. Если это первая запись группы, «ИТОГО» получает ноль, в противном случае ИТОГ будет равен [«Синий»] при индексе, вычитаемом на [«Красный»] при индексе-1.
Я попытался сделать это в функции ниже, но это не работает.
def funct(group):
count = 0
lst = []
for info in group:
if count == 0:
lst.append(0)
count = 1
else:
num = group.iloc[count]['Blue'] - group.iloc[count-1]['Red']
lst.append(num)
count = 1
group['Total'] = lst
return group
df = df.join(df.groupby('Groups').apply(funct))
Код работает для первой группы, но затем выдает ошибки.
Желаемый результат таков:
df_final = pd.DataFrame({
'Red' : [1,2,3,4,5,6,7,8,9,10],
'Groups':['A','B','A','A','B','C','B','C','B','C'],
'Blue':[10,20,30,40,50,60,70,80,90,100],
'Total':[0,0,29,37,48,0,65,74,83,92]
})
df_final
df_final.groupby('Groups').apply(print)
Спасибо вам за помощь!
Ответ №1:
Для каждой группы рассчитайте разницу между Blue
и сдвинутым Red
(красным цветом по предыдущему индексу):
df['Total'] = (df.groupby('Groups')
.apply(lambda g: g.Blue - g.Red.shift().fillna(g.Blue))
.reset_index(level=0, drop=True))
df
Red Groups Blue Total
0 1 A 10 0.0
1 2 B 20 0.0
2 3 A 30 29.0
3 4 A 40 37.0
4 5 B 50 48.0
5 6 C 60 0.0
6 7 B 70 65.0
7 8 C 80 74.0
8 9 B 90 83.0
9 10 C 100 92.0
Или, как прокомментировал @anky, вы можете избежать apply
Red
этого, сначала сдвинув столбец:
df['Total'] = (df.Blue - df.Red.groupby(df.Groups).shift()).fillna(0, downcast='infer')
df
Red Groups Blue Total
0 1 A 10 0
1 2 B 20 0
2 3 A 30 29
3 4 A 40 37
4 5 B 50 48
5 6 C 60 0
6 7 B 70 65
7 8 C 80 74
8 9 B 90 83
9 10 C 100 92
Комментарии:
1. Спасибо всем вам, я собираюсь покопаться в ваших ответах!
2. к сожалению, я не смог использовать это для решения своей проблемы из-за обобщения. Очевидно, это означает, что я плохо написал вопрос, так как ответы работают.
3. В принципе, я хочу, чтобы две группы colmun применили сложную функцию, а затем обновили столбец, а затем восстановили исходный кадр данных с помощью нового столбца.
4. Проблема с использованием лямбды в том, что я не могу получить две отдельные строки для выполнения функции.
5. к сожалению, вопрос, как я его задал, очень прост и оставляет открытым вычитание.