对numpy数组进行异构处理,以使两个相邻的小室不相等

时间:2018-10-12 07:36:32

标签: python-3.x numpy

我有一个大的numpy数组,我想使用以下条件进行填充:

  • 仅使用设置范围(0到9)范围内的数字
  • 填充使得没有相邻的单元格相等。这意味着每个单元格将被与其不同的值包围。不允许例外。

我当前正在使用以下功能

def uniqify(in_array):
    #warning: array is mutable and gets modified outside this scope
    out_array = np.arange(in_array.size).reshape(in_array.shape)
    return out_array.astype(np.float32)

但是,这违反了第一个条件,因为数组值上升到非常高的数字。由于在输入此函数之前我不知道这些数组的大小,所以我宁愿限制每个条目中可以包含的数字的大小。

有没有完美的解决方案来实现这一目标?

编辑

我目前正在查看numpy中的一些随机化功能,例如https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.randn.html

以下是我使用np.random.choice制作的示例

import numpy as np
data = np.array([[1,1,1], [1,1,1], [1,1,1]])
size = np.size(data)

for i in range(20):
    random_list = np.random.choice(size, size, replace= False)/(size-1)
    print(random_list)
print('\ndone')

这会打印各种列表,编号范围从0到1,这很好,但是对于大型数据集,我可以想象到可能的样本之间的差异很小,以致于它们几乎相等。因此,我无法随机化,但需要以明确的目标为避免相邻单元格相等来驱动函数。我想数字可以从1画到9 ...

1 个答案:

答案 0 :(得分:1)

正如Paul Panzer所说,可以构建规则的棋盘状图案:

def uniq(shape):
    f = lambda *idx: np.mod(np.sum(idx, axis=0), 10)
    return np.fromfunction(f, shape)

例如,uniq((5, 17))

[[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.  0.  1.  2.  3.  4.  5.  6.]
 [ 1.  2.  3.  4.  5.  6.  7.  8.  9.  0.  1.  2.  3.  4.  5.  6.  7.]
 [ 2.  3.  4.  5.  6.  7.  8.  9.  0.  1.  2.  3.  4.  5.  6.  7.  8.]
 [ 3.  4.  5.  6.  7.  8.  9.  0.  1.  2.  3.  4.  5.  6.  7.  8.  9.]
 [ 4.  5.  6.  7.  8.  9.  0.  1.  2.  3.  4.  5.  6.  7.  8.  9.  0.]]

没有相邻的元素相等。模数甚至可以取为mod 2,得到0-1数组。

如果您希望数组是随机的(或至少看起来是随机的),则分数步可以提供帮助。

def uniq(shape):
    steps = 1 + np.mod(np.random.randint(1, 100, size=len(shape))*(np.sqrt(5)+1)/2, 8)
    f = lambda *idx: np.mod(np.floor(np.random.uniform(0, 10) + np.moveaxis(idx, 0, -1).dot(steps)), 10)
    return np.fromfunction(f, shape)

现在uniq((5, 17))看起来很像

[[ 4.  8.  3.  7.  2.  7.  1.  6.  0.  5.  0.  4.  9.  3.  8.  3.  7.]
 [ 0.  4.  9.  4.  8.  3.  7.  2.  7.  1.  6.  0.  5.  0.  4.  9.  3.]
 [ 6.  1.  5.  0.  4.  9.  4.  8.  3.  7.  2.  7.  1.  6.  0.  5.  0.]
 [ 2.  7.  1.  6.  1.  5.  0.  4.  9.  4.  8.  3.  7.  2.  7.  1.  6.]
 [ 8.  3.  8.  2.  7.  1.  6.  1.  5.  0.  4.  9.  4.  8.  3.  7.  2.]]

第一个版本的所有步骤总计为1。步骤的计算基于黄金比率(np.sqrt(5)+1)/2,因为黄金的倍数会产生均匀分布但看起来随机的数字。步数保证在1到9之间,因此在铺设地板并采用mod 10之后,每一步我们都可以保证使用不同的数字。

相关问题