2016-10-28 2 views
0

Я работаю с серией текстового корпуса, и при этом мне нужно построить матрицу совпадений. Я в настоящее время тестирую письмо и тестирую свой код, поэтому каждый раз, когда я запускаю, я получаю другую матрицу (поскольку list(set()) неупорядочен. Я построил разреженную матрицу с помощью scipy.sparse.coo_matrix() и хотел бы иметь возможность использовать координаты и значение, генерируемые этим тип конструкции. Я полагаю, что это будет самый быстрый и памяти effictient способ сделать это. в тот момент, когда я пытаюсь получить доступ к этим значения Я преподносятИзвлечение элементов из разреженной матрицы

[<1x16 sparse matrix of type '<class 'numpy.float32'>' 
with 10 stored elements in Compressed Sparse Row format>, <1x16 sparse matrix of type '<class 'numpy.float32'>' 
with 4 stored elements in Compressed Sparse Row format>, <1x16 sparse matrix of type '<class 'numpy.float32'>' 
with 4 stored elements in Compressed Sparse Row format>, <1x16 sparse matrix of type '<class 'numpy.float32'>' 
with 7 stored elements in Compressed Sparse Row format>, <1x16 sparse matrix of type '<class 'numpy.float32'>' 

когда я print разреженную матрицу я получаю следующее:

(0, 1) 0.5 
    (0, 4) 1.0 
    (0, 6) 0.5 
    (1, 7) 1.0 
    (1, 11) 1.0 
    (1, 12) 1.0 
    (1, 13) 0.5 
    (2, 14) 0.5 
    ... 
    (15, 6) 1.0 
    (15, 9) 0.5 
    (15, 15) 3.0 
    (15, 0) 2.0 
    (15, 1) 0.5 
    (15, 6) 0.5 
    (15, 14) 1.5 

Я бы предположил, что извлечение этих значения по мере их появления возможны.

Для приведенного выше примера я извлечь следующий пример:

row = [0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 
     4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 
     9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 
     13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 
     15, 15, 15, 15, 15, 15, 15] 

column = [1, 4, 6, 7, 11, 12, 13, 14, 15, 0, 4, 9, 12, 13, 14, 15, 4, 5, 12, 13, 
     4, 9, 13, 14, 0, 1, 2, 3, 5, 8, 10, 12, 13, 14, 2, 4, 12, 13, 0, 14, 
     15, 0, 8, 11, 13, 4, 7, 10, 11, 1, 3, 12, 14, 4, 8, 11, 13, 0, 7, 8, 
     10, 0, 1, 2, 4, 5, 9, 13, 0, 1, 2, 3, 4, 5, 7, 10, 12, 0, 1, 3, 4, 6, 
     9, 15, 0, 1, 6, 14] 

values = [0.5, 1.0, 0.5, 1.0, 1.0, 1.0, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, 1.0, 0.5, 
      1.0, 0.5, 1.0, 0.5, 1.0, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 0.5, 
      0.5, 1.0, 0.5, 0.5, 1.0, 1.0, 1.5, 2.0, 1.0, 2.5, 1.0, 3.0, 1.0, 0.5, 
      1.5, 2.0, 1.0, 1.0, 2.0, 0.5, 1.0, 0.5, 2.0, 2.0, 0.5, 4.0, 0.5, 0.5, 
      0.5, 1.0, 1.0, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 2.5, 1.0, 
      4.0, 1.0, 1.0, 1.5, 1.0, 1.0, 1.0, 0.5, 1.0, 0.5, 1.0, 1.0, 0.5, 3.0, 
      2.0, 0.5, 0.5, 1.5] 

sps_array = sparse.coo_matrix((values, (row, column)), shape=(16, 16)) 

На данный момент я нахожусь в состоянии преобразовать sps_array с помощью sps_array.toarray с последующим затем создавая списки, где

list1 = list(np.nonzero(sps_array > 0)[0]) 
list2 = list(np.nonzero(sps_array > 0)[1]) 

и создание следующих for петля для восстановления координат

index = 0 
sps_coordinates = [] 

for i in range(token_size): 
    for j in range(list1_count[i]): 
     sps_coordinates.append((list1[index+j], list2[index+j])) 
    index += list1_count[i] 

я получить значения по

list(sps_array[sps_array > 0] 

Есть ли более эффективный способ, чтобы получить эти координаты и значения по отношению к тому, что я сделал?

ответ

1

С копировальной-н-пастой я построить ваш sps_array:

In [2126]: sps_array 
Out[2126]: 
<16x16 sparse matrix of type '<class 'numpy.float64'>' 
    with 88 stored elements in COOrdinate format> 

Формат coo сохраняет свои значения в 3-х атрибутах, каждый массив (полученный из 3 входных списков):

In [2127]: sps_array.data 
Out[2127]: 
array([ 0.5, 1. , 0.5, 1. , 1. , 1. , 0.5, 0.5, 1. , 1. , 0.5, 
     0.5, 1. , 0.5, 1. , 0.5, 1. , 0.5, 1. , 0.5, 0.5, 1. , 
     0.5, 1. , 1. , 1. , 1. , 0.5, 0.5, 1. , 0.5, 0.5, 1. , 
     1. , 1.5, 2. , 1. , 2.5, 1. , 3. , 1. , 0.5, 1.5, 2. , 
     1. , 1. , 2. , 0.5, 1. , 0.5, 2. , 2. , 0.5, 4. , 0.5, 
     0.5, 0.5, 1. , 1. , 0.5, 0.5, 1. , 0.5, 1. , 1. , 0.5, 
     0.5, 0.5, 2.5, 1. , 4. , 1. , 1. , 1.5, 1. , 1. , 1. , 
     0.5, 1. , 0.5, 1. , 1. , 0.5, 3. , 2. , 0.5, 0.5, 1.5]) 
In [2128]: sps_array.row 
Out[2128]: 
array([ 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 
     3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 
     6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 
     10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 
     13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 
     15, 15, 15], dtype=int32) 
In [2129]: sps_array.col 
Out[2129]: 
array([ 1, 4, 6, 7, 11, 12, 13, 14, 15, 0, 4, 9, 12, 13, 14, 15, 4, 
     5, 12, 13, 4, 9, 13, 14, 0, 1, 2, 3, 5, 8, 10, 12, 13, 14, 
     2, 4, 12, 13, 0, 14, 15, 0, 8, 11, 13, 4, 7, 10, 11, 1, 3, 
     12, 14, 4, 8, 11, 13, 0, 7, 8, 10, 0, 1, 2, 4, 5, 9, 13, 
     0, 1, 2, 3, 4, 5, 7, 10, 12, 0, 1, 3, 4, 6, 9, 15, 0, 
     1, 6, 14], dtype=int32) 

Разреженная матрица имеет nonzero метод, у которого код:

A = self.tocoo() 
    nz_mask = A.data != 0 
    return (A.row[nz_mask],A.col[nz_mask]) 

Он гарантирует, что матрица находится в формате coo, гарантирует, что в данных нет никаких «скрытых» нулей, а также возвращаются атрибуты row31031010 и col.

Это не требуется, если ваша матрица уже coo, но необходима, если матрица находится в формате csr.

Таким образом, вам не нужно проходить через плотные функции toarray и np.nonzero. Однако np.nonzero(sps_array) действительно работает, потому что он делегирует задачу sps.array.nonzero().

Применение transpose к nonzero дает массив, который может быть то, что вы хотите:

In [2136]: np.transpose(np.nonzero(sps_array)) 
Out[2136]: 
array([[ 0, 1], 
     [ 0, 4], 
     [ 0, 6], 
     [ 1, 7], 
     [ 1, 11], 
     [ 1, 12], 
     .... 

На самом деле существует функция н.п., что делает именно это (для любого массива) (посмотреть на его код или документы) :

np.argwhere(sps_array) 

(. Вам не нужно использовать nonzero(sps_array>0) - если вы не беспокоитесь о отрицательных значений)

+0

Я наблюдая странное поведение при попытке используйте '.row' или' .col' с разреженной матрицей, которую я создал. Мне присваивается атрибут «AttributeError: row not found», но когда я пытаюсь сделать то же самое для примера выше, я распечатываю список. Bevahiour отсутствует при использовании '.data' и в каждом случае значения печатаются. Мне удалось решить эту проблему, используя 'np.transpose (np.nonzero (sps_array))', предложенный @hpaulj, и нарезку для создания соответствующих списков столбцов и строк. – Lukasz

+1

Я подозреваю, что ваша редкая матрица не была в формате 'coo'. Только этот формат имеет атрибуты 'row' и' col'. 'nonzero' использует' tocoo' для преобразования своего ввода в coo (при необходимости). Не стесняйтесь придерживаться «отличного от нуля», потому что это проще. – hpaulj

Смежные вопросы