[英]How to pass a custom equality_check function into perfplot
我正在使用 perfplot 库来比较三个函数f1
、 f2
和f3
的性能。 这些函数应该返回相同的值,所以我想进行相等性检查。 但是,我可以在 inte.net 上找到的所有其他 perfplot 示例都使用pd.DataFrame.equals
或np.allclose
作为相等性检查器,但这些不适用于我的特定情况。
例如,如果函数返回不同长度的 numpy arrays 列表,则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
)
如何传递与上述功能不同的 function?
如果我们检查源代码,相等性检查的工作方式是将传递给kernels
的第一个 function 中的 output 作为参考,并将其与循环中传递给kernels
的后续函数的 output 进行比较。
出于某种原因,相等性检查会有所不同,具体取决于kernels
中的第一个 function 是否返回元组。
如果kernels
中的第一个 function 没有返回元组,它只是调用传递给equality_check
参数的 function 来执行检查。 相等性检查 function 需要两个 arguments 并且可以做任何事情。 例如,它只能检查长度是否相等并收工(即将以下 lambda 传递给equality_check
: lambda x,y: len(x) == len(y)
)。
对于问题中的示例,循环元素对并检查不等式的 function 有效。
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"
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.