2013-04-10 2 views
4

Вкратце: есть similar question, и наилучший ответ предлагает использовать numpy.bincount. Мне нужно то же самое, но для матрицы.Приращение данных индексов в матрице

У меня есть два массива:

array([1, 2, 1, 1, 2]) 
array([2, 1, 1, 1, 1]) 

вместе они составляют показатели, которые должны быть увеличен:

>>> np.array([a, b]).T 
array([[1, 2], 
     [2, 1], 
     [1, 1], 
     [1, 1], 
     [2, 1]]) 

Я хочу, чтобы получить эту матрицу:

array([[0, 0, 0], 
     [0, 2, 1], # (1,1) twice, (1,2) once 
     [0, 2, 0]]) # (2,1) twice 

Матрица будет небольшим (например, 5 × 5), а число индексов будет большим (где-то около 10^3 или 10^5).

Итак, есть ли что-нибудь лучше (быстрее), чем for -loop?

ответ

3

Вы все еще можете использовать bincount(). Хитрость состоит в том, чтобы преобразовать a и b в единый 1D массив плоских индексов.

Если матрица n х m, вы могли бы применить bincount() к a * m + b, и построить матрицу из результата.

Чтобы взять пример в вашем вопросе:

In [15]: a = np.array([1, 2, 1, 1, 2]) 

In [16]: b = np.array([2, 1, 1, 1, 1]) 

In [17]: cnt = np.bincount(a * 3 + b) 

In [18]: cnt.resize((3, 3)) 

In [19]: cnt 
Out[19]: 
array([[0, 0, 0], 
     [0, 2, 1], 
     [0, 2, 0]]) 

Если форма массива является более сложным, может быть проще использовать np.ravel_multi_index() вместо вычисления плоских индексов вручную:

In [20]: cnt = np.bincount(np.ravel_multi_index(np.vstack((a, b)), (3, 3))) 

In [21]: np.resize(cnt, (3, 3)) 
Out[21]: 
array([[0, 0, 0], 
     [0, 2, 1], 
     [0, 2, 0]]) 

(Hat наконечник @Jaime для указание ravel_multi_index.)

+0

Awesome, спасибо! – kirelagin

+3

+1 Очень приятно. ['np.ravel_multi_index'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.ravel_multi_index.html) может пригодиться, чтобы не думать слишком много о более сложных массивах. – Jaime

+0

@Jaime: Удивительно, спасибо за указатель. Я искал что-то вроде «ravel_multi_index», но не нашел его. – NPE

2
m1 = m.view(numpy.ndarray) # Create view 
m1.shape = -1 # Make one-dimensional array 
m1 += np.bincount(a+m.shape[1]*b, minlength=m1.size) 
Смежные вопросы