Итеративно передавать значения строк данных кадра (l oop) как аргументы в функции в Python - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть функция, которая требует три аргумента:

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

И фрейм данных с тремя столбцами:

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

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

Я хотел бы использовать каждую строку (с тремя столбцами и отсюда три значения) в качестве значений аргументов для функции. Наконец, я хотел бы l oop по строкам кадра данных и вернуть список.

Например, результаты должны выглядеть следующим образом:

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)
...

Я выяснил вероятно, это как-то связано с pandas.DataFrame.apply и *. Но я новичок в Python и не мог понять, как это сделать. Может ли кто-нибудь помочь, пожалуйста?

Ответы [ 4 ]

2 голосов
/ 08 февраля 2020

Вы смотрели в правильном направлении с помощью «apply»:

# 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)

Что происходит при использовании функции apply, так это то, что (в случае оси = 1) вся строка используется как первая аргумент в указанной функции. Лямбда-функция - это, по сути, оболочка, которая преобразует этот единственный аргумент (x) в три неупакованных значения и передает их в правильном порядке в следующую функцию, R0.

1 голос
/ 08 февраля 2020

Вы можете сделать:

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

Все это (была пара других вещей, нуждающихся в полировке):

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)

Выходы:

   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 голос
/ 08 февраля 2020

Если вы настаиваете на использовании pandas, вы также можете выполнять вычисления напрямую, используя numpy без функции:

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
0 голосов
/ 08 февраля 2020

df.apply(lambda x: R0(x[0], x[1], x[2]), axis=1) даст правильный результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...