2016-07-11 6 views
2

У меня есть разреженная матрица А (равной 10 * 3 в плотном), таких как:Python разреженная матрица получить максимальные значения и индекс

print type(A) 
<class scipy.sparse.csr.csr_matrix> 

print A 
(0, 0) 0.0160478743808 
(0, 2) 0.0317314165078 
(1, 2) 0.0156596521648 
(1, 0) 0.0575683686558 
(2, 2) 0.0107481166871 
(3, 0) 0.0150580924929 
(3, 2) 0.0297743235876 
(4, 0) 0.0161931803955 
(4, 2) 0.0320187296788 
(5, 2) 0.0106034409766 
(5, 0) 0.0128109177074 
(6, 2) 0.0105766993238 
(6, 0) 0.0127786088452 
(7, 2) 0.00926522256063 
(7, 0) 0.0111941023699 

В максимальных значениях для каждого столбца:

print A.max(axis=0) 
(0, 0) 0.0575683686558 
(0, 2) 0.0320187296788 

Я хотел бы получить индекс , соответствующий значению столбца. Я знаю, что

A.getcol(i).tolist()
вернет мне список каждого столбца, который позволит мне использовать функцию argmax(), но этот способ очень медленный. Мне интересно, есть ли способ спуска?

+0

Является ли ваша матрица способной вписываться в память? Выполнение 'A.todense(). Argmax (axis = 0)' будет делать то, что вы хотите, если возможно «A.todense()». – kbrose

+0

'argmax' будет хорошим дополнением к scipy разреженным матрицам. Тем временем: можете ли вы переключиться на формат CSC? Если это так, есть способ достаточно эффективно получить argmax столбцов. –

+0

@kbrose, .todense() невозможно, так как размер данных не соответствует памяти. –

ответ

1

Это небольшое изменение метода вы предложили в вопросе:

col_argmax = [A.getcol(i).A.argmax() for i in range(A.shape[1])] 

(Атрибут .A эквивалентно .toarray().)

Потенциально более эффективной альтернативой является

B = A.tocsc() 
col_argmax = [B.indices[B.indptr[i] + B.data[B.indptr[i]:B.indptr[i+1]].argmax()] for i in range(len(B.indptr)-1)] 

Любой из перечисленных выше будет работать , но я должен спросить: если ваш массив имеет форму (10, 3), почему вы используете разреженную матрицу? (10, 3) мало! Просто используйте регулярный, плотный массив numpy.

Даже если вы держите A как разреженную матрицу, наиболее эффективный способ вычисления Argmax столбцов матрицы такого размера, вероятно, просто преобразовать его в плотный массив и использовать Argmax метод:

col_argmax = A.A.argmax(axis=0) 
+0

Привет, Уоррен, большое спасибо за ваш ответ! Я тестирую ваше решение и быстрее, чем функция A.toarray() или .todense(). –

+0

Единственная проблема заключается в том, что ваш метод не работает, когда один или разреженный столбец матрицы пуст (полный на 0.). В этом случае просто верните случайное число для меня в порядке, поэтому я могу изменить бит вашего кода на: def get_max (i): try: index = B.data [B.indptr [i]: B .indptr [+ 1]] Argmax() , за исключением:. # сумма столбца равна нулю # иными словами, этот тест док не имеет любое слово появляется в поезде док индекс = -1 обратный индекс maxval_index = [B.indices [B.indptr [i] + get_max (i)] для i в диапазоне (len (B.indptr) -1)] –

+0

Зачем вы спрашиваете, почему я выбираю разреженную матрицу, так как мой действительно размер матрицы A составляет 100k * 300k, и я хотел бы вычислить скалярное произведение A с другой большой матрицей. Функция CSR.dot довольно быстро. Именно по этой причине я выбираю разреженную матрицу. –