首页 > 解决方案 > 随机生成随机数

问题描述

我有一个 column T,它决定 value 列中值的范围。 T以 0.5 的步长递增,并且始终出现 4 次。

If T=0.5,1.5,2.5etc.,我想生成一个介于 1 和 2 之间的随机数。 If T=1,2,3,4etc.,我想生成一个介于 2 和 3 之间的随机数。

^这很简单,切换随机生成器或单独生成随机数并排序它们应该可以解决问题。

但是,每 10 个整数Ts 即一次1,2,3,4...10,我想要一个随机函数来选择一个随机数T并将值设置在 5 和 6 之间,而不是 2 和 3。

同样,在 的每 100 个整数值中T,我想随机选择一个T并使Value列介于 15 和 16 之间。

T   Value
0.5 1.01
0.5 1.05
0.5 1.85
0.5 1.49
1   2.45
1   2.52
1   2.48
1   2.95
1.5 1.78
1.5 1.45
1.5 1.65
1.5 1.77
2   2.96
2   2.75
2   2.74
2   2.95
2.5 1.75
2.5 7.89
2.5 1.33
2.5 1.58
3   5.78
3   5.44
3   5.36
3   5.24

标签: pythonpython-3.xnumpyrandom

解决方案


我会这样做:

编辑:我改变了最后两个条件,因为它们实际上是多余的。)

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

也许 usingnp.where()更快,但我不希望这样,因为您可能会以这种方式为每个条件(隐藏)一个循环。

编辑(基于评论)

如果您希望这更灵活,您可以尝试类似(假设您有一个预定义的数组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)

推荐阅读