2

我有一个像这样的 N x 2 数组:

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

在此矩阵中进行搜索后,我返回一些必须置换行的索引。

就我而言,我有w=[1 0 9 8 7].

我使用此代码仅在选定行上置换 2 列。

        for x in w:
            self.nodes[x] = roll (self.nodes[x], 1)

结果是正确的,如下所示:

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

加星标的行已正确排列。

我想知道是否有一个ONE-LINER numpy 表达式可以完成所有这些技巧。

这里的重要事实是操作的速度。

4

2 回答 2

2

这通过将滚动应用于a仅 at 索引的副本,w然后a使用滚动值设置原始值:

a[w] = np.roll(a[w], 1, axis=1)

有人有一个答案(我认为@seberg,但它现在已被删除)表明对于两列滚动相当于反转,您实际上不需要roll,并且可以使用按索引反转的技巧:

a[w] = a[w, ::-1]

对于大型阵列,时间类似。对于较短的阵列,roll解决方案较慢。这是时间。

N = 10
a = np.arange(N*2).reshape(-1,2)
w = np.random.choice(np.arange(N), size=N/2, replace=False)

timeit a[w] = np.roll(a[w],1,1)
10000 loops, best of 3: 23.2 µs per loop

timeit a[w] = a[w, ::-1]
100000 loops, best of 3: 8.07 µs per loop

N = 1000
a = np.arange(N*2).reshape(-1,2)
w = np.random.choice(np.arange(N), size=N/2, replace=False)

timeit a[w] = np.roll(a[w],1,1)
10000 loops, best of 3: 113 µs per loop

timeit a[w] = a[w, ::-1]
10000 loops, best of 3: 93.6 µs per loop

N = 100000
a = np.arange(N*2).reshape(-1,2)
w = np.random.choice(np.arange(N), size=N/2, replace=False)

timeit a[w] = np.roll(a[w],1,1)
100 loops, best of 3: 10.8 ms per loop

timeit a[w] = a[w, ::-1]
100 loops, best of 3: 9.63 ms per loop
于 2013-09-23T21:34:57.623 回答
0
self.nodes[w] = np.asarray(map(lambda x: np.roll(x,1), self.nodes[w]))
于 2013-09-23T21:30:07.037 回答