nop*_*per 9 python arrays numpy shuffle
在numpy数组中有效置换每列内容的最佳方法是什么?
我所拥有的是:
>>> arr = np.arange(16).reshape((4, 4))
>>> arr
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>> # Shuffle each column independently to obtain something like
array([[ 8, 5, 10, 7],
[ 12, 1, 6, 3],
[ 4, 9, 14, 11],
[ 0, 13, 2, 15]])
Run Code Online (Sandbox Code Playgroud)
如果您的数组是多维的,np.random.permutation默认情况下沿第一轴(列)置换:
>>> np.random.permutation(arr)
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 0, 1, 2, 3],
[12, 13, 14, 15]])
Run Code Online (Sandbox Code Playgroud)
但是,这会对行索引进行混洗,因此每列具有相同的(随机)排序.
独立地对每列进行混洗的最简单方法是循环遍历列并使用np.random.shuffle将每个列混洗到位:
for i in range(arr.shape[1]):
np.random.shuffle(arr[:,i])
Run Code Online (Sandbox Code Playgroud)
例如,这给出了:
array([[12, 1, 14, 11],
[ 4, 9, 10, 7],
[ 8, 5, 6, 15],
[ 0, 13, 2, 3]])
Run Code Online (Sandbox Code Playgroud)
如果您有一个非常大的数组而不想复制,则此方法非常有用,因为每个列的排列都是在适当的位置完成的.另一方面,即使是简单的Python循环也可能非常慢,并且有更快的NumPy方法,例如@jme提供的方法.
这是另一种方法:
def permute_columns(x):
ix_i = np.random.sample(x.shape).argsort(axis=0)
ix_j = np.tile(np.arange(x.shape[1]), (x.shape[0], 1))
return x[ix_i, ix_j]
Run Code Online (Sandbox Code Playgroud)
快速测试:
>>> x = np.arange(16).reshape(4,4)
>>> permute_columns(x)
array([[ 8, 9, 2, 3],
[ 0, 5, 10, 11],
[ 4, 13, 14, 7],
[12, 1, 6, 15]])
Run Code Online (Sandbox Code Playgroud)
我们的想法是生成一堆随机数,然后argsort在每列中独立生成.这会产生每列索引的随机排列.
请注意,这具有次优的渐近时间复杂度,因为排序需要时间O(n m log m)来处理大小数组m x n.但是由于Python的for循环非常慢,所以除了非常高的矩阵外,你实际上可以获得更好的性能.
| 归档时间: |
|
| 查看次数: |
3777 次 |
| 最近记录: |