以下问题:拥有基本三联(0,1,0)
现在我尝试在给定范围内创建一个已更改的三元组列表。
约束:
在上面提到的例子中,我们的方法应该创建
lst = [(0.0, 1, 0.0),(0.02, 0.98, 0.), (0.04, 0.96,0), (0.04,0.94, 0.02), (0.06,0.94,0), (0.06, 0.92, 0.02), (0.06, 0.9, 0.04), ...]
有什么好办法吗?
也许你有想法创建这些列表而没有嵌套循环(可能有numpy?)。
非常感谢!
答案 0 :(得分:1)
您可以创建一个函数,在您描述时生成三元组......例如:
def make_triple(r=0.2, s=0.02):
element_one = round(random.uniform(0, r), 2)
max_s = r/s
element_three = random.randint(0, max_s) * s
element_two = round(1 - element_one - element_three, 2)
return (element_one, element_two, element_three)
然后创建一个调用此函数的循环:
list_of_triples = []
for i in range(5):
list_of_triples.append(make_triple(0.2, 0.02))
你去吧!不需要嵌套循环。
答案 1 :(得分:1)
这是一个列表理解,它应该提供满足你的约束的所有3元组(据我所知)。它比我想要的更笨重,因为范围函数只接受整数:
r = 0.2
s = 0.02
steps = int(math.ceil(r/s))
lst = [(a*s, 1-(a+b)*s, b*s) for b in range(steps) for a in range(steps)]
结果:
>>> lst[0:4]
[(0.0, 1.0, 0.0), (0.02, 0.98, 0.0), (0.04, 0.96, 0.0), (0.06, 0.94, 0.0)]
>>> lst[90:94]
[(0.0, 0.8200000000000001, 0.18), (0.02, 0.8, 0.18), (0.04, 0.78, 0.18), (0.06, 0.76, 0.18)]
此代码中的第一个和最后一个值仅达到0.18,并且我不确定这是否合乎需要(是约束< r或< = r?)。如果你想要另一种方式,调整它应该不会太难。
答案 2 :(得分:1)
另一个愚蠢的答案只是为了踢:
import numpy as np
r = .2
s = .02
a, b = np.mgrid[0:r:s, 0:r:s]
lst = np.dstack([a, 1 - (a+b), b]).reshape(-1, 3)
答案 3 :(得分:0)
根据要求,这里是没有for循环的NumPy解决方案。它使用3D数组和NumPy广播规则来按行和按列分配比例。 scale
是单个列的2D数组,因此.T
可以方便地进行转换。最后,3D阵列被重新整形为2D。
import numpy as np
r = .2
s = .02
scale = np.arange(r, step=s, dtype=float).reshape(-1,1)
a = np.empty((len(scale),len(scale),3), dtype=float)
a[:,:,0] = scale
a[:,:,2] = scale.T
a[:,:,1] = 1 - a[:,:,0] - a[:,:,2]
print a.reshape(-1,3)