我使用二分法计算方程中求根的函数dichotomy(),然后使用装饰器显示值print_dichotomy()。我相信最后我会看到列根 - 函数在根 - 误差 - 收敛处的值。然而,实际上,我以这样的方式得到它:只有函数的根和值预期从 columns 中显示,而其他两列是不正确的。其中,误差仅由一个值(其余行NaN)表示,并且收敛- 它的所有值都在一行中。
我没有描述该函数的本质dichotomy(),而是在其中放置 Pandas 列的伪值列表。
错误在哪里?
我的代码:
import numpy as np
import pandas as pd
def print_dichotomy(funcs):
def wrapper(a, b, eps_func, eps_arg):
*res, func, eps_list, prev_roots = list(funcs(a, b, eps_func, eps_arg))
func = list(map(lambda x: f'{f(x):.10f}', res))
result_table = pd.DataFrame()
result_table['Корни'] = pd.Series(res)
result_table['Значения функции'] = pd.Series(func)
result_table['Погрешность расчета'] = pd.Series(eps_list)
result_table['Сходимость'] = pd.Series(prev_roots)
print(result_table)
return wrapper
def f(x):
return 1.2 - np.log(x) - 4 * np.cos(2 * x)
@print_dichotomy
def dichotomy(a, b, eps_func, eps_arg):
# 1. создаем переменную-список для хранения значений корня
prev_roots = [0.01, 0.01, 0.01, 0.01, 0.01, 0.01]
# 2. создадим список для хранения погрешностей расчета
eps_list = [0.02, 0.02, 0.02, 0.02, 0.02, 0.02]
# 3. создадим список для хранения корней
roots = [0.03, 0.03, 0.03, 0.03, 0.03, 0.03]
for i in roots:
root = i
# 4. возвращаем корень
if root:
yield root
# 5. возвращаем значение погрешности расчета корня, сходимости
yield eps_list, prev_roots
dichotomy(0.0001, 50, 0.000001, 0.000001)
该错误在于函数之间数据传输和接收不正确。
dichotomy()你那里返回yield eps_list, prev_roots,这相当于yield (eps_list, prev_roots),即 两个列表的元组。您稍后会在框架中看到这些列表作为值。并且,由于这些列表没有“解压”到框架单元中,因此其余值变成了 NaN。wrapper()表达式中,*res, func, eps_list, prev_roots = list(funcs(a, b, eps_func, eps_arg))您将生成器函数返回的值dichotomy()放入变量中。从最后开始:prev_roots上述元组被传递到(eps_list, prev_roots)并填充“Convergence”列的前2行(下面没有数据,因此为NaN);eps_list列表中的最后一个(第六个)值输入-roots0.03,它也成为该列第一行的值Погрешность расчета;func列表中的倒数第二个(第五个)值输入-roots0.03,但未在其他任何地方使用(消失);roots将传递给变量res并显示在该列的四行中Корни。因此,结果是一帧 4 行,而不是预期的 6 行,并且其中的数据位置不正确。
在没有深入研究所选方法的原因并且没有消除代码冗余(例如,转换)的情况下,我对代码进行了最低程度的纠正,以便(我希望)发出所需的输出
list():pd.Series()结论:
发生了什么变化:
*res, func, eps_list, prev_roots = list(funcs(a, b, eps_func, eps_arg))删除 ,func以便结果的最后一行不会被吃掉;yield eps_list, prev_roots分成两行,否则元组返回到一个变量中,但需要将两个列表分成两部分;prev_roots为了清晰起见,测试值多样化eps_list。