2015-07-16 1 views
2

Это может быть реализовано с помощью циклов и условий, но есть быстрый эффективный способ сделать это с использованием Python и numpy, так как я работаю с матрицами, имеющими сто тысяч строк.Строки матрицы сдвига имеют максимумы в середине

В качестве примера мы имеем небольшой матрицу с 3 рядами

1, 3, 4, 10, 2, 4, 1 

2, 4, 10, 1, 1, 1, 2 

1, 4, 7, 5, 4, 10, 1 

В результате, я хочу иметь строки циклического сдвига таким образом, что максимум каждой строки находится в среднем

1, 3, 4, 10, 2, 4, 1 

2, 2, 4, 10, 1, 1, 1 

7, 5, 4, 10, 1, 1, 4 

То, что я думал о том, что-то вроде этого:

middle = matrix.shape[1]/2 
for row in range(0, matrix.shape[0]): 
    max_index = np.argmax(matrix[row, :]) 
    np.roll(matrix[row, :], middle-max_index) 

Я думаю Argmax может извлечь ll максимальные индексы для всех строк. Но как применить другой сдвиг к каждой строке, np.roll не обеспечивает такую ​​функциональность, как shift должен быть int, а не массив.

+2

Вы можете преобразовать это хороший вопрос, предоставляя код, который вы пробовали так далеко! – Kasramvd

+0

Я отредактировал мой вопрос. – Mehdi

ответ

4

Это будет один vectorized подход, предполагая A в качестве входного массива -

# Get shape info and the middle column index 
M,N = A.shape 
mid_col_idx = int(N/2) 

# Get required shifts for each row 
shifts = mid_col_idx - np.argmax(A,axis=1) 

# Get offsetted column indices 
offsetted_col_idx = np.mod(np.arange(N) - shifts[:,None],N) 

# Finally generate correctly ordered linear indices for all elements 
# and set them in A in one-go 
Aout = A.ravel()[offsetted_col_idx + N*np.arange(M)[:,None]] 

Пример запуска -

In [74]: A 
Out[74]: 
array([[ 1, 3, 4, 10, 2, 4, 1], 
     [ 2, 4, 10, 1, 1, 1, 2], 
     [ 1, 4, 7, 5, 4, 10, 1]]) 

In [75]: Aout 
Out[75]: 
array([[ 1, 3, 4, 10, 2, 4, 1], 
     [ 2, 2, 4, 10, 1, 1, 1], 
     [ 7, 5, 4, 10, 1, 1, 4]]) 
+0

Спасибо, именно то, что я искал. – Mehdi

+0

@Mehdi Полезно знать! – Divakar

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