根据Python中的条件从两个数组中随机选择

时间:2019-02-13 18:34:50

标签: python arrays python-2.7

假设我有两个长度相等的数组:

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值保持一致

2 个答案:

答案 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个值,获取该大小的可能索引的唯一样本,然后并行迭代ab,保持所选索引的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]