假设我有两个长度相等的数组:
a = [0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,0,1]
b = [0,1,1,0,1,0,0,1,1,0,0,1,1,0,1,0,0]
现在我要从这两个数组中选取元素,按照给定的顺序,使它们以a:b =的比率随机选择a&b之间的值,从而形成与a&b长度相同的新数组。 4.68,即从a选取的每1个值,在结果数组中应该从b选取的4.68个值。
因此有效地,结果数组可能类似于:
res = [0,1,1,0,1, 1(from a) ,0(from a),1,1,0,0,1,1,0, 0(from a),0,0]
res数组具有:前5个值分别来自b,a的第6和7个,b的第8-14个,b的第15个,b的第16-17个
在给定的res数组示例中,a:b的值的总比率为a:b 4.67(来自a = 3,来自b = 14)
因此,在两个数组之间,必须随机选择值,但是需要保持顺序,即不能从一个数组中获取第7个值,而从另一个数组中获取第3个值。如果要在结果数组中填充的值是第3个,则在两个输入数组的第三个元素之间随机选择。此外,还需要保持总体比率。
能否请您帮助我开发一种有效的Python方式来实现此最终解决方案?解决方案不必与每次运行的w.r.t值保持一致
答案 0 :(得分:1)
我认为这应该可行。您指定要从中获得多少(您可以简单地使用比率来计算出该数字),随机生成数字的“掩码”,然后根据或从截止值中进行选择(注意,您只能进行排序以找出数字)截止,但您稍后使用未排序的蒙版)
import numpy as np
a = [0,0,1,0,0,1,0,0,0,1,0,1,1,0,0,0,1]
b = [0,1,1,0,1,0,0,1,1,0,0,1,1,0,1,0,0]
mask = np.random.random(len(a))
from_a = 3
cutoff = np.sort(mask)[from_a]
res = []
for i in range(len(a)):
if (mask[i]>=cutoff):
res.append(a[i])
else:
res.append(b[i])
答案 1 :(得分:1)
借用Barmar's answer中的a_count
计算(因为它似乎可行,而且我不介意重新发明它),此解决方案保留了从a
中选择的值的顺序和b
:
from future_builtins import zip # Only on Python 2, to avoid temporary list of tuples
import random
# int() unnecessary on Python 3
a_count = int(round(1/(1 + 4.68) * len(a)))
# Use range on Python 3, xrange on Python 2, to avoid making actual list
a_indices = frozenset(random.sample(xrange(len(a)), a_count))
res = [aval if i in a_indices else bval for i, (aval, bval) in enumerate(zip(a, b))]
这里的基本思想是,确定所需的a
个值,获取该大小的可能索引的唯一样本,然后并行迭代a
和b
,保持所选索引的a
值,保持所有其他索引的b
值。
如果您不喜欢list
理解的复杂性,可以使用另一种方法,复制b
,然后一一填写a
值:>
res = b[:] # Copy b in its entirety
# Replace selected indices with a values
# No need to convert to frozenset for efficiency here, and it's clean
# enough to just iterate the sample directly without storing it
for i in random.sample(xrange(len(a)), a_count):
res[i] = a[i]