假设我有以下数据:
data = [1,1,3,2,4]
max_value = 4 # it is known from before
number_of_random_values = 2
我想要的是为data
的每个点创建范围在1到4之间的随机值,但不包括每个情况下的点的情况。为了更清楚地说明这一点,这里有一个例子:
data point random_values
1 -> [2,4]
1 -> [3,2]
3 -> [1,4]
2 -> [3,1]
4 -> [1,3]
因此,上面我们得到的是:对于每个数据点,两个随机值,这些随机数不能与数据点相同。到目前为止,我所做的工作如下:
desired_values = np.zeros((len(data), number_of_random_values))
range_of_data = range(1, max_value + 1)
i = 0
for data_point in data:
copy_of_range = copy.copy(range_of_data)
copy_of_range.remove(data_point)
random_values_for_data_point = random.sample(copy_of_range, number_of_random_values)
desired_values[i] = random_values_for_data_point
i = i + 1
上面的代码实现了我想要的结果(在numpy数组中需要的结果),但是很明显,它不是从性能上优化的。
是否有向量化的方法来实现这一点?还是更有效的方法?
编辑
将data
替换为
data = np.random.random_integers(max_value, size=(1000, 1)).tolist()
并将我的解决方案与以下答案中的解决方案一起运行:
import time
start_time = time.time()
for _ in range(10000):
# each solution
.
.
.
end_time = time.time()
print(end_time - start_time)
我们的结果如下:
发布于 2017-10-07 06:37:22
如果我们不对随机数使用np,我们可以做一些简单的事情,如:
import random
import numpy as np
data = [1,1,3,2,4]
max_value = 4 # it is known from before
number_of_random_values = 2
output = [random.sample([i for i in range(1,max_value+1) if i != item],2)\
for item in data]
np.array(output)
返回
array([[4, 2],
[3, 4],
[1, 4],
[1, 3],
[3, 2]])
发布于 2017-10-07 10:18:04
避免在1范围内的给定整数,max_value可以通过模块化算法实现,这在NumPy中是矢量化的:
结果同样有可能是1和max_value之间的任何数字,但排除的数字除外。(实际上,获得排除值的唯一方法是在步骤1中添加max_ value - 1,这是不允许的)。
因此,问题归结为从同一个数组生成许多样本(不排除),而不需要替换。不幸的是,目前看来NumPy还没有这方面的工具。方法numpy.random.choice
只生成一个示例,因此必须在循环中调用它。
data = np.array([1,1,3,2,4])
max_value = 4
number_of_random_values = 2
desired_values = np.zeros((len(data), number_of_random_values), dtype=np.int)
for i in range(len(data)):
desired_values[i, :] = np.random.choice(max_value-1, number_of_random_values, replace=False)
desired_values = np.mod(desired_values + data.reshape(-1, 1), max_value) + 1
注意,这个版本声明了数组desired_data
的dtype,默认情况下它将是float64。如果只期望小整数,则类型可以是np.int8
。
https://stackoverflow.com/questions/46620680
复制相似问题