Abschreibung / Berechnung auf Basis vorhergehender Zeilen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Peter1974
User
Beiträge: 3
Registriert: Freitag 25. September 2020, 12:40

Hallo Zusammen,

Ursprünglich komme ich aus der Statistik & Datenbank - Ecke und bin in Python ziemlicher Anfänger. Entsprechend habe bei meinem Problem auch schon ein paar Ideen durchprobiert, komme aber auf keinen grünen Zweig.
Vielleicht könnt Ihr mir ein paar Tips geben zur Lösung meines Problems. Skriptschnipsel lehne ich natürlich auch nicht ab :wink:

Im Prinzip geht es um eine Art Abschreibungsberechnung. Ich habe einen Anfangsbestand, eine Zeitachse (Periode) und für jede Periode eine spezifische Abschreibungsrate (bzw. hier Survival Rate = 1-Abschreibungsrate)


Mein Ausgangspunkt:

1) Ein Dataframe mit einer ID (z.B. für jedes Abschreibungsobjekt), einer Zeiteinheit und einem Faktor im Sinne einer Survival Rate.
Lesebeispiel: In Periode 4 ist Objekt mit ID1 nur noch 0,99 vom Wert der Vorperiode 3.

df_start = pd.DataFrame({
'id' : [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3],
'zeit' : [1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,11,12,13,1,2,3,4,5,6,7,8,9,10,11],
'faktor' : [1,0.99,0.99,0.99,0.99,0.99,0.99,0.99,0.99,0.99,1,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,1,0.9,0.9,0.9,0.9,0.7,0.7,0.7,0.7,0.7,0.7],
})

2) die Ausgangswerte - Der Wert jeder ID-Nummer zum Zeitpunkt 1:
df_basis = pd.DataFrame ({"id": [1,2,3],
"wert": [100, 200, 300]})


Mein Ziel:

df_ziel = pd.DataFrame({
'id' : [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3],
'zeit' : [1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,11,12,13,1,2,3,4,5,6,7,8,9,10,11],
'faktor' : [1,0.99,0.99,0.99,0.99,0.99,0.99,0.99,0.99,0.99,1,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,0.95,1,0.9,0.9,0.9,0.9,0.7,0.7,0.7,0.7,0.7,0.7],
'ergebnis' : [100,99,98.01,97.0299,96.059601,95.09900499,94.1480149401,93.206534790699,92.274469442792,91.3517247483641,200,190,180.5,171.475,162.90125,154.7561875,147.018378125,139.66745921875,132.684086257812,126.049881944922,119.747387847676,113.760018455292,108.072017532527,300,270,243,218.7,196.83,137.781,96.4467,67.51269,47.258883,33.0812181,23.15685267]
})

Das Ergebnis berechnet sich dabei jeweils aus dem Wert der Vorperiode * Faktor der Periode.
Also z.B. Startwert 100 in Periode 1 reduziert sich zu 100*0,99 in Periode 2 zu 100*0,99*0,99 in Periode 3, usw.

Da sich die Faktoren im Zeitverlauf ändern können, ist eine einfaches "100*faktor**zeit" leider keine Option.


Meine Herausforderung:

Wie schaffe ich es, zeilenübergreifend zu arbeiten und den Wert einer Periode aus dem Wert der Vorperiode zu berechnen?


Wäre toll, wenn Ihr ein paar Ideen und Tips für mich hättet.

Beste Grüße
Peter
Benutzeravatar
__blackjack__
User
Beiträge: 13163
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Schau Dir mal die `shift()`-Methode an, ob Dir die eventuell weiterhilft.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Sirius3
User
Beiträge: 17780
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Datenstruktur ist für solche Daten vielleicht nicht die beste. Die mathematische Operation, die du brauchst, ist cumprod. Da du für jedes Objekt eine unterschiedliche Anzahl an Zeitschritten hast, macht die Sache schwierig
Peter1974
User
Beiträge: 3
Registriert: Freitag 25. September 2020, 12:40

Sirius3 hat geschrieben: Freitag 25. September 2020, 15:21 Die Datenstruktur ist für solche Daten vielleicht nicht die beste. Die mathematische Operation, die du brauchst, ist cumprod. Da du für jedes Objekt eine unterschiedliche Anzahl an Zeitschritten hast, macht die Sache schwierig
Vielen Dank für den Tip! Für die erste ID passiert genau das, was ich am Ende haben will. Aber wie bringe ich Python dazu, bei der zweiten ID wieder von vorne anzufangen?

Mein Versuch mit

for i in df['id']:
df['test'] = df['faktor'].cumprod(axis=0)

führte jedenfalls nicht zum gewünschten Resultat :oops:
Benutzeravatar
__blackjack__
User
Beiträge: 13163
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Peter1974: Da wird man nach ID gruppieren müssen → `groupby()`.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Peter1974
User
Beiträge: 3
Registriert: Freitag 25. September 2020, 12:40

__blackjack__ hat geschrieben: Freitag 25. September 2020, 17:10 @Peter1974: Da wird man nach ID gruppieren müssen → `groupby()`.
Sehr cool 8)
Am Ende wird aus dem ganzen Problem ein sehr überschaubarer Zweizeiler:

gdf = df.groupby('id', group_keys = True)
df['test'] = gdf['faktor'].cumprod(axis=0)

Bin begeistert! :D

Vielen Dank Euch beiden für die guten Tips!
Antworten