Estou tentando usar a função pandas.cumsum(), mas de uma forma que ignora linhas com um valor na coluna ID que está duplicado e especificamente adiciona apenas o último valor à soma cumulativa, ignorando todos os valores anteriores. Exemplo de código abaixo (não consegui compartilhar o código real, que é para trabalho).
import pandas as pd, numpy as np
import random as rand
id = ['a','b','c','a','b','e','f','a','b','k']
value = [12,14,3,13,16,7,4,6,10,18]
df = pd.DataFrame({'id':id, 'value':value})
df["cumsum_of_value"] = df['value'].cumsum()
df["desired_output"] = [
12,26,29,30,32,39,43,36,30,48
]
df["comments"] = [""]*len(df)
df.loc[df.index==0, "comments"]="standard cumsum"
df.loc[df.index==1, "comments"]="standard cumsum"
df.loc[df.index==2, "comments"]="standard cumsum"
df.loc[df.index==3, "comments"]="cumsum of rows 1-3, ignore row 0"
df.loc[df.index==4, "comments"]="cumsum of rows 2-4, ignore rows 0, 1"
df.loc[df.index==5, "comments"]="cumsum of rows 2-5, ignore rows 0, 1"
df.loc[df.index==6, "comments"]="cumsum of rows 2-6, ignore rows 0, 1"
df.loc[df.index==7, "comments"]="cumsum of rows 2,4-7, ignore rows 0, 1, 3"
df.loc[df.index==8, "comments"]="cumsum of rows 2,5-8, ignore rows 0, 1, 3, 4"
df.loc[df.index==9, "comments"]="cumsum of rows 2,5-9, ignore rows 0, 1, 3, 4"
print(df)
Neste exemplo, existem sete (7) valores exclusivos na coluna ID (a, b, c, d, e, f, g), portanto, o cumsum deve somar no máximo sete (7) registros como sua saída em qualquer linha.
Isso é possível usando combinações de funções como cumsum(), groupby(), duplicado(), drop_duplicates() e evitando o uso de um loop iterativo?
Eu tentei o abaixo
df["duped"] = np.where(df["id"].duplicated(keep='last'),0,1)
df["value_duped"] = df["duped"] * df["value"]
df["desired_output_attempt"] = df["cumsum_of_value"] - df["value_duped"]
Mas não chega perto da resposta correta. Não consigo pensar em como fazer algo assim resultar na saída desejada sem iterar.
Tentar:
Impressões:
Código
Se você não tiver muitos valores exclusivos para
id
, acho que você pode usarpivot
++ffill
.sum
df:
Experimente isso.
Eu li sua descrição. Aqui está minha opinião.