Оптимальный способ выполнения матричного произведения на основе условия - PullRequest
0 голосов
/ 23 января 2019

Я работаю с: x = pd.DataFrame(np.random.randint(0,10,size=(20, N))) с N>5000 и y = np.random.dirichlet(np.ones(20),size=1).

Я выполнял матричный продукт между каждыми x столбцами и y (который представляет собой список весов с суммой 1), чтобы получить массив из N элементов, поэтому я использую x.T.dot(y).

Теперь я хотел бы изменить вычисление моего матричного произведения: для каждого 0 в текущем столбце X, который вычисляется, мы переоцениваем y, не считая вес, который был бы умножен на 0 и равномерно распределен это между весами, которые будут умножены на значения, отличные от 0, поэтому сумма списка по-прежнему равна 1.

Пример с меньшими структурами

x

       a1   a2   a3
b1     1    5    6
b2     3    0    0
b3     9    7    0

и y = [0.3, 0.5, 0.2]

Ожидаемый результат: [3.6, 5.9, 6]

Шаг 1: без нулей -> простое средневзвешенное значение (0.3*1+0.5*3+0.2*9 = 3.6)

Шаг 2: (b2,a2) = 0, поэтому y становится [0.55, 0, 0.45] и 0.55*5+0.45*7 = 5.9

Шаг 3: (b2,a3) & (b3,a3) = 0, поэтому y становится [1, 0, 0], а общее число равно 6.

Специфичность: структура фрейма данных построена так, что при наличии 0 следующие ячейки в одной строке будут равны 0.

1 Ответ

0 голосов
/ 23 января 2019

Вы можете построить новую матрицу с той же формой, что и A, сложив y, отрегулировать ее с помощью маски, затем выполнить поэлементное умножение и суммирование по столбцам:

y= np.array([0.3, 0.5, 0.2])
A = np.array([[1, 5, 6],
       [3, 0, 0],
       [9, 7, 0]])
m = A == 0
new_y = np.repeat(y,A.shape[1]).reshape(A.shape)
new_y = (new_y + (new_y*m).sum(axis=0)/(~m).sum(axis=0))*~m
result = (new_y * A).sum(axis=0)
result
>> array([3.6 5.9 6. ])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...