2

X我有一个包含R行和C列的数组。我希望生成一个名为的新数组a_array,其中每个元素将根据其对应行的均值和标准差随机生成X。使用 Numpy 执行此操作的最 Pythonic 和最有效的方法是什么?

目前,我正在使用嵌套循环来生成逐元素数字。

a_array = np.zeros(shape=(a_size, X.shape[0]))
for i in range(a_size):
    for j in range(X.shape[0]):
        a_array[i][j] = np.random.randint(low=X[i].mean()-X[i].std(), high=X[i].mean()+X[i].std())

编辑:对不起,我忘记了一些东西,但我也想确保 a_array 的每一行都包含唯一的元素(任何行中都没有重复的元素)。到目前为止,我还没有想到任何方法来实现这一目标。

4

2 回答 2

1

只需删除 for 循环的一个级别并生成一个随机数向量来替换整行而不是一次替换位置

a_array = np.zeros(shape=(a_size, X.shape[0]))
for i in range(a_size):
    a_array[i] = np.random.randint(\
                      low=X[i].mean()-X[i].std(),\ 
                      high=X[i].mean()+X[i].std(),\
                      size=(1,a_array.shape[1]))
于 2019-04-18T17:01:18.733 回答
1

部分矢量化

我们可以将其减少到一个循环 -

m,s = X[:a_size].mean(1),X[:a_size].std(1)
L = (m-s).astype(int)
H = (m+s).astype(int)
out = np.empty((a_size,X.shape[0]),dtype=int)
for i,(l,h) in enumerate(zip(L,H)):
    out[i] = np.random.choice(np.arange(l,h),X.shape[0],replace=False)

基本理念:

  1. 沿第二个轴计算平均值和标准值。在此之前,我们需要切片X以将其限制为a_size行数,如果a_size不是X.

  2. 在最初的循环版本中,我们使用random.randintwith mean-std 和 mean+std 作为限制。因此,对于建议的版本,使用步骤#1 中的平均值和标准值获取下限和上限。

  3. 使用这些低值和高值运行一个循环,np.random.choice(np.arange(l,h),X.shape[0],replace=False)以设置可供选择的值范围,并选择大小的随机值X.shape[0]和具有replace=False.

完全矢量化

我们可以使用12中列出的技巧使其完全矢量化,从而为我们提供类似于以下内容的内容,以替换前面列出的循环步骤:

R = H-L
MX = R.max()
n = X.shape[0]
unqIDs = np.random.rand(len(L),MX).argpartition(axis=1,kth=n)[:,:n]
out = unqIDs%R[:,None] + L[:,None]

请注意,这将占用更多内存。

于 2019-04-18T17:03:15.480 回答