Вопрос по sparse-matrix, numpy, scipy, python, aggregate – Эффективное нарезание матриц с использованием умножения матриц, с Python, NumPy, SciPy

3

Я хочу изменить 2dscipy.sparse.csr.csr_matrix(давайте назовем этоA) в 2dnumpy.ndarray (давайте назовем этоB).

A может быть

>shape(A)
(90, 10)

затемB должно быть

>shape(B)
(9,10)

где каждые 10 рядовA будет изменен в новое новое значение, а именно максимум этого окна и столбца. Оператор столбца не работает с этим непригодным для использования типом разреженной матрицы. Как я могу получить этоB с помощью умножения матриц?

Я могу'Не думаю, что можно сделать это быстро на разреженном массиве. Но даже(9000, 1000) массив может быть обработан в около100 ms на моей системе делаетrows, cols = sparse_mat.shape а потом .np.max(sparse_mat.toarray().reshape(rows // 10, 10, cols), axis=1) Jaime
спасибо за комментарии, в моем случае это занимает несколько секунд, потому что матрицы намного больше. Но я положил некоторые предварительные знания, что ты неt have: количество строк значительно превышает количество столбцов, поэтому я буду циклически перебирать столбцы, менять форму каждого и вычислять максимум. Это не то, что я хотел, но кажется, что нет ничего радикально быстрее. Milla Well
@MillaWell вы попробовали ответ ниже? Saullo G. P. Castro
Я неЯ думаю, что матричное умножение является опцией длямаксимальная, может быть длясумма, Рассматривали ли вы вместо этого формат CSC, который поддерживает нарезку столбцов? Jaime

Ваш Ответ

1   ответ
1

Используя матричное умножение, вы можете сделать эффективное разделение, создавая "ломтерезки» матрица с единицами в нужных местах. Нарезанная матрица будет иметь то же самоеtype как "ломтерезки», так что вы можете эффективно контролировать свой тип вывода.

Ниже вы увидите некоторые сравнения, и наиболее эффективным для вас является запрос.A матрица и нарезать его. Это оказалось намного быстрее, чем.toarray() метод. Использование умножения является вторым самым быстрым вариантом, когда "ломтерезки» создается какndarray, умноженный наcsr матрица и нарезать результат.

OBS: используяcoo разреженный для матрицыA привело к немного медленнее времени, сохраняя те же пропорции, иsol3 не применимо, я понял позже, что в умножении он преобразуется вcsr автоматически.

import scipy
import scipy.sparse.csr as csr
test = csr.csr_matrix([
[11,12,13,14,15,16,17,18,19],
[21,22,23,24,25,26,27,28,29],
[31,32,33,34,35,36,37,38,39],
[41,42,43,44,45,46,47,48,49],
[51,52,53,54,55,56,57,58,59],
[61,62,63,64,65,66,67,68,69],
[71,72,73,74,75,76,77,78,79],
[81,82,83,84,85,86,88,88,89],
[91,92,93,94,95,96,99,98,99]])

def sol1():
    B = test.A[2:5]

def sol2():
    slicer = scipy.array([[0,0,0,0,0,0,0,0,0],
                          [0,0,0,0,0,0,0,0,0],
                          [0,0,1,0,0,0,0,0,0],
                          [0,0,0,1,0,0,0,0,0],
                          [0,0,0,0,1,0,0,0,0]])
    B = (slicer*test)[2:]
    return B

def sol3():
    B = (test[2:5]).A
    return B

def sol4():
    slicer = csr.csr_matrix( ((1,1,1),((2,3,4),(2,3,4))), shape=(5,9) )
    B = ((slicer*test).A)[2:] # just changing when we do the slicing
    return B

def sol5():
    slicer = csr.csr_matrix( ((1,1,1),((2,3,4),(2,3,4))), shape=(5,9) )
    B = ((slicer*test)[2:]).A
    return B


timeit sol1()
#10000 loops, best of 3: 60.4 us per loop

timeit sol2()
#10000 loops, best of 3: 91.4 us per loop

timeit sol3()
#10000 loops, best of 3: 111 us per loop

timeit sol4()
#1000 loops, best of 3: 310 us per loop

timeit sol5()
#1000 loops, best of 3: 363 us per loop

РЕДАКТИРОВАТЬ: ответ был обновлен заменой.toarray() от.A, давая гораздо более быстрые результаты, и теперь лучшие решения находятся на вершине

Похожие вопросы