как сделать эффективно большую разреженную матрицу в python? - PullRequest
1 голос
/ 17 апреля 2020

1. я пытаюсь сделать массив numpy с формой: (6962341, 268148), введите: np.uint8

2. у меня есть данные, состоящие из [x1, x2, x3, x4], [x2, x1], [x4, x5, x3] ...

3. я хочу назначить массив [x1, x2] + = 1, массив [x1, x3] + = 1, массив [x1, x4] + = 1, массив [x2, x3] + = 1, ...

4. поэтому я попробовал функцию следующей структуры:


import numpy as np
from itertools import combinations

base_array = np.zeros((row_size, col_size), dtype=np.uint8))

for each_list in data:
  for (x,y) in list(combinations(each_list,2)):
    if x>y:
      base_array[y,x] += 1
    else:
      base_array[x,y] += 1

, в основном она вычисляет верхний треугольник матрицы, и я буду использовать значение верхнего треугольника. Также вы можете думать, что это похоже на создание базовой матрицы A для матрицы совместного использования. но эта функция слишком медленная, и я думаю, что можно сделать быстрее. Что мне делать?

1 Ответ

0 голосов
/ 17 апреля 2020

Предполагая, что ваши данные являются целыми числами (поскольку они представляют строки и столбцы), или вы можете иметь sh ваши данные x1, x2, ... в 1, 2, ... целых числах, вот быстрое решение:

#list of pairwise combinations in your data
comb_list = []
for each_list in data:
  comb_list += list(combinations(each_list,2))

#convert combination int to index (numpy is 0 based indexing)
comb_list = np.array(comb_list) - 1

#make array with flat indices
flat = np.ravel_multi_index((comb_list[:,0],comb_list[:,1]),(row_size,col_size))

#count number of duplicates for each index using np.bincount
base_array = np.bincount(flat,None,row_size*col_size).reshape((row_size,col_size)).astype(np.uint8)

пример данные:

[[1, 2, 3, 4], [2, 1], [4, 5, 3, 4]]

Соответствующий вывод:

[[0 1 1 1 0]
 [1 0 1 1 0]
 [0 0 0 2 0]
 [0 0 1 1 1]
 [0 0 1 1 0]]

РЕДАКТИРОВАТЬ: соответствует объяснению в комментариях:

data=[[1, 2, 3, 4], [2, 1], [4, 5, 3, 4]]
base_array = np.zeros((len(data), np.max(np.amax(data))), dtype=np.uint8)

for i, each_list in enumerate(data):
  for j in each_list:
    base_array[i, j-1] = 1

Выход:

[[1 1 1 1 0]
 [1 1 0 0 0]
 [0 0 1 1 1]]
...