提问人:cottontail 提问时间:11/24/2022 更新时间:11/24/2022 访问量:149
如何将自定义equality_check函数传递到 perfplot 中
How to pass a custom equality_check function into perfplot
问:
我正在使用 perfplot 库来比较三个函数的性能,并且 .这些函数应该返回相同的值,因此我想进行相等性检查。但是,我可以在互联网上找到所有其他 perfplot 示例或作为相等检查器,但这些不适用于我的特定情况。f1
f2
f3
pd.DataFrame.equals
np.allclose
例如,如果函数返回不同长度的 numpy 数组列表,则不起作用。np.allclose
import perfplot
import numpy as np
def f1(rng):
return [np.array(range(i)) for i in rng]
def f2(rng):
return [np.array(list(rng)[:i]) for i in range(len(rng))]
def f3(rng):
return [np.array([*range(i)]) for i in rng]
perfplot.show(
kernels=[f1, f2, f3],
n_range=[10**k for k in range(4)],
setup=lambda n: range(n),
equality_check=np.allclose # <-- doesn't work; neither does pd.DataFrame.equals
)
如何传递与上述函数不同的函数?
答:
0赞
cottontail
11/24/2022
#1
如果我们检查源代码,相等性检查的工作方式是将传递给的第一个函数的输出作为引用,并将其与循环中传递给的后续函数的输出进行比较。kernels
kernels
出于某种原因,相等性检查会有所不同,具体取决于 中的第一个函数是否返回元组。kernels
如果 中的第一个函数不返回元组,则它只是调用传递给参数的函数来执行检查。相等性检查函数接受两个参数,可以执行任何操作。例如,它只能检查长度是否相等并称其为一天(即将以下 lambda 传递给 : )。kernels
equality_check
equality_check
lambda x,y: len(x) == len(y)
对于问题中的示例,一个循环元素对并检查不等式的函数起作用。
def equality_check(x, y):
for i, j in zip(x, y):
if not np.allclose(i, j):
return False
return True
perfplot.show(
kernels=[f1, f2, f3],
n_range=[10**k for k in range(4)],
setup=lambda n: range(n),
equality_check=equality_check
)
事实上,也有效。all()
perfplot.show(
kernels=[f1, f2, f3],
n_range=[10**k for k in range(4)],
setup=lambda n: range(1, n+1),
equality_check=lambda x,y: all([x,y])
)
从源代码复制的以下代码是实现相等性检查的代码段:
for k, kernel in enumerate(self.kernels):
val = kernel(*data)
if self.equality_check:
if k == 0:
reference = val
else:
try:
if isinstance(reference, tuple):
assert isinstance(val, tuple)
assert len(reference) == len(val)
is_equal = True
for r, v in zip(reference, val):
if not self.equality_check(r, v):
is_equal = False
break
else:
is_equal = self.equality_check(reference, val)
except TypeError:
raise PerfplotError(
"Error in equality_check. "
+ "Try setting equality_check=None."
)
else:
if not is_equal:
raise PerfplotError(
"Equality check failure.\n"
+ f"{self.labels[0]}:\n"
+ f"{reference}:\n\n"
+ f"{self.labels[k]}:\n"
+ f"{val}:\n"
)
评论