Numpy:洗牌元素的子集
Numpy: shuffle subset of elements
我有一个二维 numpy 数组,将其解释为一个网格,并且想要排列元素的一个子集。
更准确地说,边应映射到边,角应映射到角。
np.random.shuffle
完成工作,当元素的任何排列都很好时。
我可以通过以下方式进入角落:
a = np.arange(16).reshape((4,4))
a[[0,0,-1,-1],[0,-1,0,-1]]
然而,当我打电话时
np.random.shuffle(a[[0,0,-1,-1],[0,-1,0,-1]])
数组未更改。阅读https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html,我发现上面使用了高级切片,returns一个副本,而不是一个视图。
但是这个副本是就地打乱的,所以没有结果分配给原始数组。
所以问题是,如何排列所选索引的元素?
您可以使用 np.random.permutation
获取输入序列的随机副本,然后使用索引对其进行分配:
In [19]: a = np.arange(16).reshape((4,4))
In [20]: a
Out[20]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [21]: a[[0,0,-1,-1],[0,-1,0,-1]] = np.random.permutation(a[[0,0,-1,-1],[0,-1,0,-1]])
In [22]: a
Out[22]:
array([[12, 1, 2, 15],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 0, 13, 14, 3]])
此外,您可以使用a[::a.shape[0]-1, ::a.shape[1]-1]
获得阵列4个角的视图
但是,由于其结果是一个二维 numpy 数组,因此洗牌只会沿第一个轴洗牌。
罪魁祸首是 np.random.shuffle 确实就地更改了数组并且从不 returns 更改值,随机排列条目。您的代码更改了包含角的新临时数组,该数组已更改,但您没有引用它,因此您看不到任何更改。查看:
>>> import numpy as np
>>> a = np.arange(16).reshape((4,4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> np.random.shuffle(a)
>>> a
array([[12, 13, 14, 15],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 0, 1, 2, 3]])
>>> np.random.shuffle(a)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[12, 13, 14, 15],
[ 8, 9, 10, 11]])
>>> a[[0,0,-1,-1],[0,-1,0,-1]]
array([ 0, 3, 8, 11])
>>> np.random.shuffle(a[[0,0,-1,-1],[0,-1,0,-1]])
>>> b = a[[0,0,-1,-1],[0,-1,0,-1]]
>>> np.random.shuffle(b)
>>> b
array([ 0, 11, 8, 3])
>>>
现在您只需使用 b 重新分配角即可。请注意,我示例中的角是从已经洗牌的数组 a.
中取出的
我有一个二维 numpy 数组,将其解释为一个网格,并且想要排列元素的一个子集。 更准确地说,边应映射到边,角应映射到角。
np.random.shuffle
完成工作,当元素的任何排列都很好时。
我可以通过以下方式进入角落:
a = np.arange(16).reshape((4,4))
a[[0,0,-1,-1],[0,-1,0,-1]]
然而,当我打电话时
np.random.shuffle(a[[0,0,-1,-1],[0,-1,0,-1]])
数组未更改。阅读https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html,我发现上面使用了高级切片,returns一个副本,而不是一个视图。 但是这个副本是就地打乱的,所以没有结果分配给原始数组。
所以问题是,如何排列所选索引的元素?
您可以使用 np.random.permutation
获取输入序列的随机副本,然后使用索引对其进行分配:
In [19]: a = np.arange(16).reshape((4,4))
In [20]: a
Out[20]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [21]: a[[0,0,-1,-1],[0,-1,0,-1]] = np.random.permutation(a[[0,0,-1,-1],[0,-1,0,-1]])
In [22]: a
Out[22]:
array([[12, 1, 2, 15],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 0, 13, 14, 3]])
此外,您可以使用a[::a.shape[0]-1, ::a.shape[1]-1]
但是,由于其结果是一个二维 numpy 数组,因此洗牌只会沿第一个轴洗牌。
罪魁祸首是 np.random.shuffle 确实就地更改了数组并且从不 returns 更改值,随机排列条目。您的代码更改了包含角的新临时数组,该数组已更改,但您没有引用它,因此您看不到任何更改。查看:
>>> import numpy as np
>>> a = np.arange(16).reshape((4,4))
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> np.random.shuffle(a)
>>> a
array([[12, 13, 14, 15],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 0, 1, 2, 3]])
>>> np.random.shuffle(a)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[12, 13, 14, 15],
[ 8, 9, 10, 11]])
>>> a[[0,0,-1,-1],[0,-1,0,-1]]
array([ 0, 3, 8, 11])
>>> np.random.shuffle(a[[0,0,-1,-1],[0,-1,0,-1]])
>>> b = a[[0,0,-1,-1],[0,-1,0,-1]]
>>> np.random.shuffle(b)
>>> b
array([ 0, 11, 8, 3])
>>>
现在您只需使用 b 重新分配角即可。请注意,我示例中的角是从已经洗牌的数组 a.
中取出的