Numpy:获取比率组合列表,使它们都加到 1

Numpy: getting a list of combinations of ratios such that they all add to 1

假设我有三种不同颜色的油漆,我想测试当我以不同比例混合它们时会发生什么。我如何获得这些比率的列表?

我可以像这样使用嵌套 for-loops 来做到这一点:

for i in np.linspace(0, 1, 6):
    for j in np.linspace(0, 1, 6):
        for k in np.linspace(0, 1, 6):
            if np.isclose(i+j+k, 1.0): ## catch floating point errors
                print(i, j, k)

这会输出以下内容:

0.0 0.0 1.0
0.0 0.2 0.8
0.0 0.4 0.6
0.0 0.6 0.4
0.0 0.8 0.2
0.0 1.0 0.0
0.2 0.0 0.8
0.2 0.2 0.6
0.2 0.4 0.4
0.2 0.6 0.2
0.2 0.8 0.0
0.4 0.0 0.6
0.4 0.2 0.4
0.4 0.4 0.2
0.4 0.6 0.0
0.6 0.0 0.4
0.6 0.2 0.2
0.6 0.4 0.0
0.8 0.0 0.2
0.8 0.2 0.0
1.0 0.0 0.0

每一行都有三个数字,它们加起来都是一个,对于我指定的分辨率,我有所有可能的组合。它可以工作,但它是一个笨拙的结构,并且它需要为我添加的每种新颜色的油漆创建一个新循环。如果我想混合 10 种涂料,我需要 10 个循环!

有没有更elegant/pythonic的方法呢?可能是 built-in numpy 函数?

(而且我发现标题中的问题很难概括,谁能想出更简洁的描述问题的方式?)

您可以为此使用 itertools.product;实际上,这是与替换的组合。您可以构造一个列表推导式,过滤总和等于 1。

from itertools import product

res = np.array([i for i in product(np.linspace(0, 1, 6), repeat=3) if sum(i) == 1])

# array([[ 0. ,  0. ,  1. ],
#        [ 0. ,  0.2,  0.8],
#        [ 0. ,  0.4,  0.6],
#        [ 0. ,  0.6,  0.4],
#        [ 0. ,  0.8,  0.2],
#        [ 0. ,  1. ,  0. ],
#        [ 0.2,  0. ,  0.8],
#        [ 0.2,  0.2,  0.6],
#        [ 0.2,  0.4,  0.4],
#        [ 0.2,  0.6,  0.2],
#        [ 0.2,  0.8,  0. ],
#        [ 0.4,  0. ,  0.6],
#        [ 0.4,  0.2,  0.4],
#        [ 0.4,  0.4,  0.2],
#        [ 0.4,  0.6,  0. ],
#        [ 0.6,  0. ,  0.4],
#        [ 0.6,  0.2,  0.2],
#        [ 0.6,  0.4,  0. ],
#        [ 0.8,  0. ,  0.2],
#        [ 0.8,  0.2,  0. ],
#        [ 1. ,  0. ,  0. ]])