2013-09-23 3 views
2

У меня есть N на 2 массива, как этот:Реверс определенные строки в N на 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]] * 

отмеченные звездочкой строки были правильно переставлять.

Я хочу знать, если есть Однострочник NumPy выражение, которое делает весь этот трюк.

Важным фактом здесь является скорость операции.

+1

Что делать, если есть двухстрочное выражение, которое в десять раз быстрее? Вы не заинтересованы? – DSM

+1

Мне интересно, но я подозревал, что oneliner, который не содержит выражений python, создается с помощью одной функции numpy (как это было обнаружено), и этот numpy быстрее, чем python. – alinsoar

+0

Но если вы знаете что-то так же удобно, как 2 из этих ответов, напишите здесь;). – alinsoar

ответ

2

Это работает, применяя бросок к копии a только индексы 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 
+0

в моем случае, как я писал в заголовке, реверс похож на смещение. – alinsoar

+0

Ницца! Красивый ! – alinsoar

+1

Да, я работаю здесь с простой перестановкой, а не со сложными структурами данных, поэтому для кодирования цикла достаточно 2 столбца. – alinsoar

0
self.nodes[w] = np.asarray(map(lambda x: np.roll(x,1), self.nodes[w])) 
+1

Я боюсь, что даже если это oneliner, он работает медленнее, чем код, который я написал;). – alinsoar

+0

Я сделал один лайнер, который бы разрешил проблему. Поскольку я думаю, что глупо хотеть однострочных, если не-однострочники выполняют быстро и читабельны, я сосредоточился на вашем запросе на одно, однострочное, и проигнорировал ваш неуместный запрос для двух несвязанных вещей, однострочный -ность и производительность. – ely

Смежные вопросы