如何在Python中快速生成这些向量?
假设我想要生成长度如何在Python中快速生成这些向量?,python,Python,假设我想要生成长度n的所有向量,使得n位置的k分量精确地为+1或-1(不限制为+1或-1),其余的n-k分量都为零 我可以按如下方式编写代码: from itertools import combinations, product result = [] for x in combinations(range(n),k): for y in product([-1,1],repeat=k) zero = [0] * n for a in x:
n
的所有向量,使得n
位置的k
分量精确地为+1或-1(不限制为+1或-1),其余的n-k分量都为零
我可以按如下方式编写代码:
from itertools import combinations, product
result = []
for x in combinations(range(n),k):
for y in product([-1,1],repeat=k)
zero = [0] * n
for a in x:
for b in y:
zero[a] = b
result.append(zero)
这种方法可行,但我觉得有点乏味。有没有快速的方法给出结果?让我们编写一个函数,用
k
1s和n-k
0s生成所有长度向量n
:
def gen(n, k):
for indices in itertools.combinations(range(n), k):
l = [0] * n
for i in indices:
l[i] = 1
yield(l)
然后,让我们将一些1转换为-1:
def gen(n, k):
for indices in itertools.combinations(range(n), k):
# each one of indices can be -1 or +1
for i in range(len(indices) + 1):
for neg_indices in itertools.combinations(indices, i):
l = [0] * n
for i in indices:
l[i] = 1
for i in neg_indices:
l[i] = -1
yield(l)
样本输出:
>>> list(gen(3, 2))
[[1, 1, 0], [-1, 1, 0], [1, -1, 0], [-1, -1, 0], [1, 0, 1], [-1, 0, 1], [1, 0, -1], [-1, 0, -1], [0, 1, 1], [0, -1, 1], [0, 1, -1], [0, -1, -1]]
您最初的实现相当接近;要解决此问题,请执行以下操作:
def gen(n, k):
for x in itertools.combinations(range(n), k):
for y in itertools.product([-1,1], repeat=k):
zero = [0] * n
for a, b in zip(x, y):
zero[a] = b
yield zero
注意使用zip
而不是嵌套。您所需要的就是
import random
import itertools
# create a single sample vector containing the distribution of elements
base_list = map(lambda x: random.choice([1,-1]), range(k)) + [0]*(n-k)
# generate all unique permutations of this list
result = set(itertools.permutations(base_list))
result
现在将按base\u列表中包含的基向量的值包含所有唯一排列
结果置换都保证有k
元素为-1或1,而n-k
元素为零
set()
负责确保排除重复条目,因为permutations()
permutes by index,而不是value-被排除在外
对于大型的n
,此实现无疑会很慢,但对于小型列表,应该足够了。您确定这符合您的要求吗?你的内部循环看起来很奇怪,而且你产生的输出似乎与你的描述不符。你为什么不添加一个例子来说明你希望向量是什么样子呢。对+1和-1没有限制(那么所有+1都可以),或者你想要一个随机分布吗?你可以使用numpy
快速生成向量,其中n个随机位置中的k个用+1或-1填充,其余的用零填充。直接使用itertools.permutations()
有什么不对itertools.permute([1]*k+[0]*(n-k))
应该足够了。您可以使用set()
排除重复项。添加一个一行:set([pl表示映射中的p(排列,[[0]*(n-k)+l表示映射中的l[[1]*i+[-1]*(k-i)表示映射中的i(k+1)]),表示映射中的pl])