Вопрос по numpy, sparse-matrix, python, scipy – Эффективный способ нормализовать скудную разреженную матрицу

22

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

from pylab import *
import scipy.sparse as sp

def normalize(W):
    z = W.sum(0)
    z[z < 1e-6] = 1e-6
    return W / z[None,:]

w = (rand(10,10)
AFAICT это 'дубликатstackoverflow.com/questions/8358962/... Emmet
Это в основном дубликат:stackoverflow.com/questions/12237954/... как это неНе имеет значения, является ли построчное поэлементное умножение или деление. Конечно, если у кого-то есть лучший ответ, отлично :) seberg
Большое спасибо! sterne
Я не согласен, это другая проблема. Дубликат, на который вы указали, выполняет поэлементное умножение, в то время как этот вопрос, кажется, хочет разделить каждую строку на другое значение (а не на все ненулевые элементы на одно и то же значение). Аарон МакДейдПриведенное ниже решение должно работать эффективно (и не требует копирования данных). conradlee

Ваш Ответ

3   ответа
1

Хотя ответ Аарона верен, я реализовал решение, когда хотел нормализоваться относительно максимумаабсолютный ценности, которые склеарн не предлагает. Мой метод использует ненулевые записи и находит их в массиве csr_matrix.data для быстрой замены значений там.

def normalize_sparse(csr_matrix):
    nonzero_rows = csr_matrix.nonzero()[0]
    for idx in np.unique(nonzero_rows):
        data_idx = np.where(nonzero_rows==idx)[0]
        abs_max = np.max(np.abs(csr_matrix.data[data_idx]))
        if abs_max != 0:
            csr_matrix.data[data_idx] = 1./abs_max * csr_matrix.data[data_idx]

В отличие от СунанВ этом случае этот метод не требует преобразования матрицы в плотный формат (что может вызвать проблемы с памятью) и умножения матриц. Я проверил метод на разреженной матрице формы (35 '000, 486 '000) и это заняло ~ 18 секунд.

37

Это было реализовано вscikit-learn sklearn.preprocessing.normalize.

from sklearn.preprocessing import normalize
w_normalized = normalize(w, norm='l1', axis=1)

axis=1 следует нормализовать по строкам,axis=0 нормализовать по столбцу. Используйте необязательный аргументcopy=False изменить матрицу на месте.

Обратите внимание, что если вы нормализуете по признакам (axis = 0), то возвращаемая матрица имеет тип 'CSC» даже если бы былксо», Это может быть неприятно, если вы рассчитываете, чтоксо» Leo
3

вот мое решение.

  • транспонировать А
  • рассчитать сумму каждого кол
  • диагональная матрица формата B с обратной величиной суммы
  • A * B равно нормализации
  • транспонировать C

    import scipy.sparse as sp
    import numpy as np
    import math
    
    minf = 0.0001
    
    A = sp.lil_matrix((5,5))
    b = np.arange(0,5)
    A.setdiag(b[:-1], k=1)
    A.setdiag(b)
    print A.todense()
    A = A.T
    print A.todense()
    
    sum_of_col = A.sum(0).tolist()
    print sum_of_col
    c = []
    for i in sum_of_col:
        for j in i:
            if math.fabs(j)

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