我会这样做:
(编辑:我更改了最后两个条件,因为它们实际上是多余的。)
(EDIT2:我更新了 10/100 偏移量变化随机发生 - 但在函数定义处设置一次。)
import random
def rand_gen_t(
t,
n0=random.randint(1, 100),
n1=random.randint(1, 10)):
if t % n0 == 0:
offset = 15
elif t % n1 == 0:
offset = 5
elif t % 1 == 0:
offset = 1
elif t % 0.5 == 0:
offset = 2
return offset + random.random()
与@DillonDavis 提出的解决方案相比,它适用于任意t,只要它是一个半整数值,并且假设您感兴趣的范围总是大小为1,并且所有都是改变是偏移量(根据您的问题内容,这是正确的)。
我会留给你定义其他输入值应该做什么。
如果您希望它能够像您的标记所建议的那样处理numpy.ndarray,我将只使用np.vectorize 函数装饰器,例如:
import numpy as np
rand_gen_t_arr = np.vectorize(rand_gen_t)
在时间方面,提议的 Numpy 解决方案在这里不会真正大放异彩,但也不是那么糟糕:
%timeit [rand_gen_t(x / 2) for x in range(1000)]
# 1000 loops, best of 3: 490 µs per loop
%timeit rand_gen_t_arr(np.arange(1000) / 2)
# 1000 loops, best of 3: 523 µs per loop
也许使用np.where() 更快,但我不希望这样,因为您可能会以这种方式为每个条件(隐藏)一个循环。
编辑(基于 cmets)
如果您希望这更灵活,您可以尝试类似(假设您有一个预定义的数组t_arr,包含T 的值):
import numpy as np
# I assume that you have it somehow, but I generate one for completeness
t_arr = np.arange(1, 1000) / 2
# first generate random numbers between 0 and 1
val_arr = np.random.random(t_arr.shape)
# update for values of `T`
int_mask = np.where(t_arr % 1 == 0)[0]
half_int_mask = np.where(t_arr % 0.5 == 0)[0]
int_offset = 1
half_int_offset = 2
val_arr[int_mask] += int_offset
val_arr[half_int_mask] += half_int_offset
# update `Value` for exceptional cases
def gen_special_mask(n_special, n_max):
return np.random.randint(1, n_special, int(n_max / n_special)) + np.arange(0, n_max, n_special)
def mask_intersect(mask1, mask2):
return np.array(list(set(mask1).intersection(set(mask2))))
special_mask10 = gen_special_mask(10, val_arr.size)
special10_offset = 5
special_mask100 = gen_special_mask(100, val_arr.size)
special100_offset = 10
special_mask10_int = mask_intersect(int_mask, special_mask10)
val_arr[special_mask10_int] += (special10_offset - int_offset)
special_mask10_half_int = mask_intersect(half_int_mask, special_mask10)
val_arr[special_mask10_half_int] += (special10_offset - half_int_offset)
special_mask100_int = mask_intersect(int_mask, special_mask10)
val_arr[special_mask100_int] += (special100_offset - int_offset)
special_mask100_half_int = mask_intersect(half_int_mask, special_mask10)
val_arr[special_mask100_half_int] += (special100_offset - half_int_offset)