Numpy: быстрый способ заполнения матрицы сопутствующих явлений - PullRequest
1 голос
/ 01 марта 2020

У меня длинный список кортежей индексов (множество дубликатов) и матрица из n на n индексов. Каждый кортеж представляет совместное вхождение.

Например:

a = np.zeros(shape=(indexCount,indexCount))

Я пробовал это:

for i1,i2 in coocPairs:  #for instance (2374, 22003)
   a[i1][i2}+=1  #takes way too long

или:

np.put(a,coocPairs,1) #which obviously does not increment

или также:

np.add(a,coocPairs,1) #which takes even longer.

В идеальном мире была бы функция, которая берет мой список кортежей и строит с ним матрицу совпадений, но, увы (делать c. не очень полезно) , Я думаю, что решение могло бы быть больше на стороне кода python, но у меня закончились идеи. Любая помощь приветствуется. Спасибо за ваше время,

Ответы [ 2 ]

1 голос
/ 01 марта 2020

Вы можете использовать collections.Counter, чтобы получить значения, которые фактически появятся в матрице. Это работает, потому что кортежи являются хэшируемыми. Задание становится довольно простым:

counts = collections.Counter(coocPairs)
ind = np.array(list(counts.keys())).T
a[ind[0], ind[1]] = list(counts.values())

Как правило, np.unique с return_counts=True заменяет Counter. В этом случае необходимо указать ось и иметь в виду, что это будет одно из более медленных решений:

ind, count = np.unique(coocPairs, return_counts=True, axis=0)
a[ind.T[0], ind.T[1]] = count

Вместо этого вы можете преобразовать свои пары в линейные индексы в уравненной матрице. :

ind = np.ravel_multi_index(tuple(np.array(coocPairs).T), a.shape)

Теперь вы можете сделать

ind, count = np.unique(ind, return_counts=True)
a.ravel()[ind] = count

В качестве альтернативы вы можете использовать np.bincount, чтобы получить счет намного быстрее, или np.add.at, чтобы избежать предварительный подсчет. Решение bincount с округленным индексом избавляет вас от необходимости предварительного распределения a:

ind = np.ravel_multi_index(tuple(np.array(coocPairs).T), (n, n))
a = np.bincount(ind, minlength=n * n).reahape(n, n)
1 голос
/ 01 марта 2020

Вы можете использовать np.add.at

np.add.at(a,tuple(coocPairs.T),1)

Если этого недостаточно, существуют более быстрые, но менее простые решения на основе np.bincount. Те полагаются на уплощенную индексацию, используя np.ravel_multi_index.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...