如果您有许多具有正确中位数和平均值的较小数组,您可以将它们组合起来生成一个更大的数组。
因此...您可以像目前正在做的那样预先生成较小的数组,然后随机组合它们以获得更大的n。当然,这将导致有偏差的随机样本,但听起来您只是想要大致随机的东西。
这里是一个工作(py3)代码,它使用大小为4、6、8、10、...、18的较小样本生成了一个大小为5000的样本,并具有您所需的属性。
请注意,我更改了如何构建较小的随机样本:如果中位数为6.5,则一半的数字必须是<= 6,另一半必须是>= 7,因此我们独立生成这些半数。这会极大地加快速度。
import collections
import numpy as np
import random
rs = collections.defaultdict(list)
for i in range(50):
n = random.randrange(4, 20, 2)
while True:
x=np.append(np.random.randint(2, 7, size=n//2), np.random.randint(7, 41, size=n//2))
if x.mean() == 12 and np.median(x) == 6.5:
break
rs[len(x)].append(x)
def random_range(n):
if n % 2:
raise AssertionError("%d must be even" % n)
r = []
while n:
i = random.randrange(4, min(20, n+1), 2)
if n - i == 2: continue
xs = random.choice(rs[i])
r.extend(xs)
n -= i
random.shuffle(r)
return r
xs = np.array(random_range(5000))
print([(i, list(xs).count(i)) for i in range(2, 41)])
print(len(xs))
print(xs.mean())
print(np.median(xs))
输出:
[(2, 620), (3, 525), (4, 440), (5, 512), (6, 403), (7, 345), (8, 126), (9, 111), (10, 78), (11, 25), (12, 48), (13, 61), (14, 117), (15, 61), (16, 62), (17, 116), (18, 49), (19, 73), (20, 88), (21, 48), (22, 68), (23, 46), (24, 75), (25, 77), (26, 49), (27, 83), (28, 61), (29, 28), (30, 59), (31, 73), (32, 51), (33, 113), (34, 72), (35, 33), (36, 51), (37, 44), (38, 25), (39, 38), (40, 46)]
5000
12.0
6.5
输出的第一行显示最终数组中有620个2,52个3,440个4等。
n
必须是偶数?(否则中位数将是一个整数。) - Mark Dickinson