scipy csr_matrix: понимать indptr

Время от времени мне приходится манипулировать csr_matrix но я всегда забываю, как indices параметров и indptr работают вместе, чтобы создать разреженную матрицу.

Я ищу четкое и интуитивно понятное объяснение того, как indptr взаимодействует как с параметрами data и с indices при определении разреженной матрицы с использованием обозначения csr_matrix((data, indices, indptr), [shape=(M, N)]).

Я могу видеть из документации scipy, что параметр data содержит все ненулевые данные, а параметр indices содержит столбцы, связанные с этими данными (как таковые, indices равны col в примере, приведенном в документации). Но как мы можем четко indptr параметр indptr?

Ответ 1

Может быть, это объяснение поможет понять концепцию:

  • data - это массив, содержащий все ненулевые элементы разреженной матрицы.
  • indices - это массив, отображающий каждый элемент в data на его столбец в разреженной матрице.
  • Затем indptr отображает элементы data и indices в строки разреженной матрицы. Это сделано по следующим причинам:

    1. Если разреженная матрица имеет M строк, indptr является массивом, содержащим M + 1 элементов
    2. для строки i[indptr[i]:indptr[i+1]] возвращает индексы элементов, взятых из data и indices, соответствующих строке i. Предположим, что indptr[i]=k и indptr[i+1]=l, данные, соответствующие строке i, будут data[k:l] в столбцах indices[k:l]. Это сложная часть, и я надеюсь, что следующий пример поможет понять ее.

РЕДАКТИРОВАТЬ: я заменил числа в data буквами, чтобы избежать путаницы в следующем примере.

enter image description here

Примечание: значения в indptr обязательно увеличиваются, потому что следующая ячейка в indptr (следующая строка) ссылается на следующие значения в data и indices, соответствующие этой строке.

Ответ 2

Конечно, элементы внутри indptr находятся в порядке возрастания. Но как объяснить поведение indptr? Короче говоря, до тех пор, пока элемент внутри indptr не станет прежним или не увеличится, вы можете пропустить индекс строки разреженной матрицы.

Следующий пример иллюстрирует приведенную выше интерпретацию элементов indptr:

Пример 1) Представьте себе эту матрицу:

array([[0, 1, 0],
       [8, 0, 0],
       [0, 0, 0],
       [0, 0, 0],
       [0, 0, 7]])


mat1 = csr_matrix(([1,8,7], [1,0,2], [0,1,2,2,2,3]), shape=(5,3))
mat1.indptr
# array([0, 1, 2, 2, 2, 3], dtype=int32)
mat1.todense()  # to get the corresponding sparse matrix

Пример 2) Массив в CSR_matrix (случай, когда разреженная матрица уже существует):

arr = np.array([[0, 0, 0],
                [8, 0, 0],
                [0, 5, 4],
                [0, 0, 0],
                [0, 0, 7]])


mat2 = csr_matrix(arr))
mat2.indptr
# array([0, 0, 1, 3, 3, 4], dtype=int32)
mat2.indices
# array([0, 1, 2, 2], dtype=int32)
mat.data
# array([8, 5, 4, 7], dtype=int32)