Python笛卡尔积和条件?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python笛卡尔积和条件?相关的知识,希望对你有一定的参考价值。
在Python中,我使用itertools.product()函数来生成用于仿真的输入参数。
我有一个测试函数,需要4个输入参数a1,a2,b1和b2。我使用以下代码生成参数。示例:
params = itertools.product(range(10,41,2), range(10,41,2), range(0, 2), range(5, 31, 5))
…这给了我3072个组合。不幸的是,某些组合在逻辑上是没有意义的。例如如果a2大于a1,则测试结果是无用的,而且当b1等于0时,b2的值也就完全无关紧要了,因此测试这样的组合没有任何意义。
除了手动执行和嵌套for循环外,是否有可能限制或过滤笛卡尔积?因为我的实际用例有4个以上的参数,所以这就是为什么我喜欢itertools提供的笛卡尔积函数的便利。
有什么想法或选择吗?任何帮助表示感谢,谢谢。
[如果您有很多参数,则使用python-constraint之类的模块的基于约束的方法可能更易于使用-让它辛苦地找出哪些组合有效。
这看起来像
from constraint import Problem
prob = Problem()
prob.addVariables(["a1", "a2"], range(10,41,2))
prob.addVariable("b1", [0, 2])
prob.addVariable("b2", range(5, 31, 5))
prob.addConstraint(lambda a1, a2: a2 <= a1, ["a1", "a2"])
prob.addConstraint(lambda b1, b2: b1 != 0 or b2 == 5, ["b1", "b2"])
for params in prob.getSolutionIter():
run_sim(**params)
Python 3
在Python 3中,您可以使用itertools.filterfalse过滤掉不良组合:
# predicate is true when need to skip the combination
predicate = (lambda (a1, a2, b1, b2): a1 <= a2 and (b1 != 0 or b2 == 5), params)
filtered_params = itertools.filterfalse(predicate, params)
Python 2
您可以使用列表理解或itertools.ifilter
:
itertools.ifilter
请注意,这两个版本都会循环播放并在引擎盖下过滤掉。如果要避免这种情况,则需要构造一种改进的算法来创建元组而不会出现不良情况。
一个选项是使filtered_params = itertools.ifilter
(lambda (a1, a2, b1, b2): a1 <= a2 and (b1 != 0 or b2 == 5), params)
成为另一个由params
本身提供的生成器。
例如:
itertools.product
您可以根据条件在params = (prod for prod in itertools.product(...) if prod[2] <= prod[1])
之后添加任何内容。例如,if
将检查您在问题中陈述的条件,仅让您通过所需的结果,并丢弃所有未通过测试的产品。
在这种情况下,使用numpy的向量运算来表达您的规则可能是最方便/直观/可读的。例如:
prod[2] <= prod[1] and prod[3] != 0
您可以结合使用列表理解和对所选参数的任何限制。我建议在执行此操作之前将参数放在一组中,以确保没有不必要的代码。在上面提到的情况下,我不会发生这种情况,但是并不总是使用import numpy as np
arr = np.array(list(params), dtype = [('a1',int),('a2',int),('b1',int),('b2',int)])
arr = arr[ arr['a2'] <= arr['a1'] ]
arr = arr[ arr['b1'] != 0 ]
来生成参数选项。
例如,在此创建一个元组参数列表,如果参数1大于参数2 + 10,则该列表仅是有效的组合:
range
以上是关于Python笛卡尔积和条件?的主要内容,如果未能解决你的问题,请参考以下文章