Ich habe eine Funktion, die drei Argumente erfordert:

def R0(confirm, suspect,t):
    p = 0.695
    si = 7.5
    yt = suspect * p + confirm
    lamda = math.log(yt)/t
    R0 = 1 + lamda * si + p * (1 - p) * pow(lamda * si,2)   
    return R0

Und ein Datenrahmen mit drei Spalten:

data = {'confirm':  ['41', '41', '43', '44'],
        'suspect': ['0', '0', '0', '10'],
        't': ['0', '1', '2', '3']
        }

df = pd.DataFrame (data, columns = ['confirm','suspect', 't'])

Ich möchte jede Zeile (mit drei Spalten und damit drei Werten) als Argumentwert für die Funktion verwenden. Zum Schluss möchte ich die Zeilen des Datenrahmens durchlaufen und eine Liste zurückgeben.

Zum Beispiel sollten die Ergebnisse so aussehen:

result = [R0_Value1, R0_Value2, R0_Value3, ....] where
R0_Value1 = R0(41, 0, 0)
R0_Value2 = R0(41, 0, 1)
R0_Value3 = R0(43, 0, 2)
...

Ich finde heraus, dass es wahrscheinlich etwas mit pandas.DataFrame.apply und * zu tun hat. Aber ich bin neu in Python und konnte nicht herausfinden, wie es geht. Könnte jemand bitte helfen?

0
June 8 Feb. 2020 im 12:10

4 Antworten

Beste Antwort

Sie haben mit 'bewerben' in die richtige Richtung geschaut:

# Convert values to int (now strings, which will throw an error in R0)
df = df.applymap(int)

df['results'] = df.apply(lambda x: R0(x.confirm, x.suspect, x.t), axis=1)

Wenn Sie die Apply-Funktion verwenden, wird (bei Achse = 1) die gesamte Zeile als erstes Argument in der angegebenen Funktion verwendet. Die Lambda-Funktion ist im Grunde ein Wrapper, der dieses einzelne Argument (x) in die drei entpackten Werte umwandelt und diese in der richtigen Reihenfolge an die nächste Funktion, R0, übergibt.

2
Araldo van de Kraats 8 Feb. 2020 im 09:47

Du kannst tun:

df["formula"]=df.apply(lambda x: R0(*x), axis=1)

Das Ganze (es gab noch ein paar andere Dinge, die poliert werden mussten):

import pandas as pd
import math

def R0(confirm, suspect,t):
    p = 0.695
    si = 7.5
    yt = suspect * p + confirm
    lamda = math.log(yt)/max(t,1) #you need to handle division by 0 somehow
    R= 1 + lamda * si + p * (1 - p) * math.pow((lamda * si),2)
    return R

data = {'confirm':  ['41', '41', '43', '44'],
        'suspect': ['0', '0', '0', '10'],
        't': ['0', '1', '2', '3']
        }

df = pd.DataFrame(data, columns = ['confirm','suspect', 't']).astype(int) #note it has to be numeric to conduct all the arithmetics you are doing later

df["formula"]=df.apply(lambda x: R0(*x), axis=1)

Ausgänge:

   confirm  suspect  t     formula
0       41        0  0  193.285511
1       41        0  1  193.285511
2       43        0  2   57.274157
3       44       10  3   31.297989
1
Grzegorz Skibinski 8 Feb. 2020 im 10:32

df.apply(lambda x: R0(x[0], x[1], x[2]), axis=1) liefert das richtige Ergebnis.

0
June 8 Feb. 2020 im 09:25

Wenn Sie darauf bestehen, pandas zu verwenden, können Sie die Berechnungen auch direkt mit numpy ohne Funktion durchführen:

df = pd.DataFrame (data, columns = ['confirm','suspect', 't']).astype(int)

p = 0.695
si = 7.5

df['results'] = 1 +(np.log(df["suspect"]*p + df["confirm"])/df["t"])*si \
                  + p*(1-p)*np.power((np.log(df["suspect"]*p + df["confirm"])/df["t"])*si,2)
print (df)

#
   confirm  suspect  t     results
0       41        0  0         inf
1       41        0  1  193.285511
2       43        0  2   57.274157
3       44       10  3   31.297989
1
Henry Yik 8 Feb. 2020 im 09:56