2016-01-12 2 views
2

Есть ли способ применить bincount с "ось = 1"? Желаемый результат будет таким же, как список понимания:Применить bincount к каждой строке двумерной матрицы numpy

import numpy as np 
A = np.array([[1,0],[0,0]]) 
np.array([np.bincount(r,minlength = np.max(A) + 1) for r in A]) 

#array([[1,1] 
#  [2,0]]) 
+0

'bincount' (для скорости) и требует 1d-массив. Таким образом, ваше выражение выглядит хорошо. Как вы, кажется, понимаете, для повторной сборки результата в массив требуется постоянное количество ящиков. Эта проблема может быть причиной того, что 'bincount' равно 1d - его приложение к строкам общего массива 2d будет создавать оборванный список. – hpaulj

+0

Я предполагаю, что это имеет смысл, но разве вы не думаете, что мое решение ниже выглядит странно? Это довольно распространенная ситуация в компьютерном обучении, чтобы таким образом вычислить количество строк. – maxymoo

+2

Вопрос в 2013 году: может ли многоквартирный сборник работать с 2D-массивами ?: http://stackoverflow.com/questions/19201972/can-numpy-bincount-work-with-2d-arrays – hpaulj

ответ

1

Если данные слишком велики для этого, чтобы быть эффективным, то проблема, скорее всего, будет использование памяти плотной матрицы, а не численное сам работает. Ниже приведен пример использования sklearn хеширование векторизатор на матрице, которая является слишком большим, чтобы использовать метод bincounts (результаты представляют собой разреженную матрицу):

import numpy as np 
from sklearn.feature_extraction.text import HashingVectorizer 
h = HashingVectorizer() 
A = np.random.randint(100,size=(1000,100))*10000 
A_str = [" ".join([str(v) for v in i]) for i in A] 

%timeit h.fit_transform(A_str) 
#10 loops, best of 3: 110 ms per loop 
1

np.bincount не работает с 2D массива вдоль некоторой ось. Чтобы получить желаемый эффект с помощью одного векторизованного вызова до np.bincount, можно создать 1D массив идентификаторов, чтобы разные строки имели разные идентификаторы, даже если эти элементы одинаковы. Это приведет к тому, что элементы из разных строк не будут объединены друг с другом при использовании одного вызова до np.bincount с этими идентификаторами. Таким образом, такой идентификатор массив может быть создан с идеей linear indexing в виду, например, так -

N = A.max()+1 
id = A + (N*np.arange(A.shape[0]))[:,None] 

Затем покормить идентификаторы np.bincount и, наконец, изменить форму обратно в 2D -

np.bincount(id.ravel(),minlength=N*A.shape[0]).reshape(-1,N) 
Смежные вопросы