2

I have an N by 2 array like this one:

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

After I make a search in this matrix, I return some indices where the rows must be permuted.

In my case, I had w=[1 0 9 8 7].

I use this code to permute the 2 columns ONLY on selected rows.

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

The result is correct like this:

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

The starred rows were correctly permuted.

I want to know if there is a ONE-LINER numpy expression that does all this trick.

The important fact here is the speed of the operation.

3
  • 1
    What if there's a two-line expression which is ten times faster? You're not interested? Commented Sep 23, 2013 at 21:33
  • 1
    I am interested, but I suspected that a oneliner that does not contain python expressions is made by a single numpy function (as it happened to discover), and this numpy is faster than python. Commented Sep 23, 2013 at 21:46
  • But if you know something as convenient as 2 of these answers , write here ;). Commented Sep 23, 2013 at 21:47

2 Answers 2

2

This works by applying the roll to a copy of a only at indices w and then setting those in the original a with the rolled values:

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

Someone had an answer (I think @seberg, but it's now deleted) that showed that for two columns rolling is equivalent to reversing, you do not actually need to roll, and can use the reversing by index trick as so:

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

For large arrays, the timing is similar. For shorter arrays, the roll solution is slower. Here is the timing.

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
Sign up to request clarification or add additional context in comments.

2 Comments

in my case , as I wrote in title, reversing is similar to shifting.
Yes, I am working here with a simple permutation , not with complicated data structures, so 2 columns are enough to encode the cycle.
0
self.nodes[w] = np.asarray(map(lambda x: np.roll(x,1), self.nodes[w]))

1 Comment

I am afraid that even if this is oneliner, it works slower than the code I wrote ;).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.