如何使用 Python 根据数据集的列查找动态函数的根

Posted

技术标签:

【中文标题】如何使用 Python 根据数据集的列查找动态函数的根【英文标题】:How to find a root of a dynamic function based in columns of a dataset using Python 【发布时间】:2020-03-07 14:51:50 【问题描述】:

我是 python 的初学者,我需要将 R 中的一些代码翻译成 Python。

我需要在基于动态函数的数据集中每行找到一个根,R中的代码是:

library(rootSolve
library(dplyr)
library(plyr)

 dataset = data.frame(A = c(10,20,30),B=c(20,10,40), FX = c("A+B-x","A-B+x","A*B-x"))

 sol<- adply(dataset,1, summarize,
               solution_0= uniroot.all(function(x)(eval(parse(text=as.character(FX),dataset))),lower = -10000, upper = 10000, tol = 0.00001))

此代码返回 [30,-10,1200] 作为每一行的解。

在 python 中,我阅读了 sciPy 包优化的文档,但没有找到适合我的代码:

我尝试了以下类似的解决方案,但没有成功:

import pandas as pd
from scipy.optimize import fsolve as fs

data = 'A': [10,20,30],
        'B': [20,10,40],
        'FX': ["A+B-x","A-B+x","A*B-x"]
df = pd.DataFrame(data)

def func(FX):
    return(exec(FX))

fs(func(df.FX),x0=0,args=df) 

有人知道如何解决这个问题吗?

非常感谢。

【问题讨论】:

【参考方案1】:

SymPy 是 Python 的符号数学库。你的问题可以这样解决:

import pandas as pd
from sympy import Symbol, solve
from sympy.parsing.sympy_parser import parse_expr

data = 'A': [10,20,30],
        'B': [20,10,40],
        'FX': ["A+B-x","A-B+x","A*B-x"]

df = pd.DataFrame(data)

x = Symbol("x", real=True)

for index, row in df.iterrows():
    F = parse_expr(row['FX'], local_dict='A': row['A'], 'B': row['B'], 'x':x)
    print (row['A'], row['B'], row['FX'], "-->", F, "-->", solve(F, x))

这个输出:

10 20 A+B-x --> 30 - x --> [30]
20 10 A-B+x --> x + 10 --> [-10]
30 40 A*B-x --> 1200 - x --> [1200]

请注意,SymPy 的解决方案返回解决方案列表。如果您确定总有一个解决方案,只需使用solve(F, x)[0]。 (请记住,与 R 不同,Python 总是从 0 开始索引。)

使用列表理解,您可以将解决方案编写为:

sol = [ solve(parse_expr(row['FX'], local_dict='A': row['A'], 'B': row['B'], 'x':x),
              x)[0] for _, row in df.iterrows() ]

如果您有很多列,您还可以使用循环创建字典:dict(c:row[c] for c in df.columns, **'x':x) )。如果您想在列表理解中组合字典,则需要奇怪的 ** 语法。字典联合见this post。

cols = df.columns # change this if you won't need all columns
sol = [ solve(parse_expr(row['FX'],
                         local_dict=dict(c:row[c] for c in cols, **'x':x) ),
              x)[0].evalf() for _, row in df.iterrows() ]

PS:SymPy 通常将解决方案保留为符号形式,因为它更喜欢精确的表达式。当有例如分数或平方根,它们不会立即计算。要获取评估表,请使用evalf(),如solve(F, x)[0].evalf()

【讨论】:

谢谢,还有一个问题,是否需要为所有列创建字典?我可以做类似 R 的“附加”功能吗?因为我的数据集有数百列,而且这个字典会很大。再次感谢您。 由于每一行都需要自己的变量值,因此您需要为每一行创建(或更新)字典。如果您知道某些行仅使用列的子集,则可以将字典限制为仅这些列。无论如何,创建字典并不是解决方案中最慢的部分。

以上是关于如何使用 Python 根据数据集的列查找动态函数的根的主要内容,如果未能解决你的问题,请参考以下文章

如何使用分析窗口 SQL 函数在同一数据集的多组行中查找 id 值

Tkinter:获取数据集的单选按钮和查找数据集之间匹配和不匹配的函数

python怎么从excel中读取数据?

如何根据 azure databricks 中的列值将静态值传递给动态值

使用 Spark 执行“WHERE IN”子句,如何仅重新训练第一个数据集的列?

如何在 Google Bigquery 中创建动态更改数据集的查询?