Альтернативы np.newaxis () для экономии памяти при сравнении массивов - PullRequest
1 голос
/ 22 января 2020

Я хочу скопировать каждый вектор из одного массива со всеми векторами из другого массива и посчитать, сколько символов соответствует одному вектору. Позвольте мне показать пример. У меня есть два массива, a и b . Для каждого вектора в a я хочу сравнить его с каждым вектором в b . Затем я хочу вернуть новый массив с размером np.array((len(a),14)), где каждый вектор содержит количество векторов, которые в a имели 0,1,2,3,4, .., 12,13 совпадений. с векторами от b . Желаемые результаты показаны в массиве c ниже.

Я уже решил эту проблему с помощью np.newaxis(), но моя проблема заключается в (см. Мою функцию ниже), что это занимает так много памяти, поэтому мой компьютер не может справиться с этим, когда a и b становятся больше. Следовательно, я ищу более эффективный способ сделать это вычисление, так как это мешает моей памяти много времени добавлять измерения к векторам. Одним из решений является go с нормой для l oop, но этот метод довольно медленный.

Можно ли сделать эти вычисления более эффективными?

a = array([[1., 1., 1., 2., 1., 1., 2., 1., 0., 2., 2., 2., 2.],
           [0., 2., 2., 0., 1., 1., 0., 1., 1., 0., 2., 1., 2.],
           [0., 0., 0., 1., 1., 0., 2., 1., 2., 0., 1., 2., 2.],
           [1., 2., 2., 0., 1., 1., 0., 2., 0., 1., 1., 0., 2.],
           [1., 2., 0., 2., 2., 0., 2., 0., 0., 1., 2., 0., 0.]])

b = array([[0., 2., 0., 0., 0., 0., 0., 1., 1., 1., 0., 2., 2.],
           [1., 0., 1., 2., 2., 0., 1., 1., 1., 1., 2., 1., 2.],
           [1., 2., 1., 2., 0., 0., 0., 1., 1., 2., 2., 0., 2.],
           [0., 1., 2., 0., 2., 1., 0., 1., 2., 0., 0., 0., 2.],
           [0., 2., 2., 1., 2., 1., 0., 1., 1., 1., 2., 2., 2.],
           [0., 2., 2., 1., 0., 1., 1., 0., 1., 0., 2., 2., 1.],
           [1., 0., 2., 2., 0., 1., 0., 1., 0., 1., 1., 2., 2.],
           [1., 1., 0., 2., 1., 1., 1., 1., 0., 2., 0., 2., 2.],
           [1., 2., 0., 0., 0., 1., 2., 1., 0., 1., 2., 0., 1.],
           [1., 2., 1., 2., 2., 1., 2., 0., 2., 0., 0., 1., 1.]])

c = array([[0, 0, 0, 2, 1, 2, 2, 2, 0, 0, 1, 0, 0, 0],
           [0, 0, 0, 0, 2, 3, 1, 2, 1, 1, 0, 0, 0, 0],
           [0, 0, 0, 3, 2, 4, 1, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 3, 0, 3, 2, 1, 1, 0, 0, 0, 0, 0],
           [0, 0, 1, 1, 4, 0, 3, 0, 1, 0, 0, 0, 0, 0]])

Мое решение :

def new_method_test(a,b):
    test = (a[:,np.newaxis] == b).sum(axis=2)
    zero     = (test == 0).sum(axis=1)
    one      = (test == 1).sum(axis=1)
    two      = (test == 2).sum(axis=1)
    three    = (test == 3).sum(axis=1)
    four     = (test == 4).sum(axis=1)
    five     = (test == 5).sum(axis=1)
    six      = (test == 6).sum(axis=1)
    seven    = (test == 7).sum(axis=1)
    eight    = (test == 8).sum(axis=1)
    nine     = (test == 9).sum(axis=1)
    ten      = (test == 10).sum(axis=1)
    eleven   = (test == 11).sum(axis=1)
    twelve   = (test == 12).sum(axis=1)
    thirteen = (test == 13).sum(axis=1)
    c = np.concatenate((zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen), axis = 0).reshape(14,len(a)).T
    return c

Спасибо за помощь.

1 Ответ

0 голосов
/ 22 января 2020

добро пожаловать в Stackoverflow! Я думаю, что для l oop это путь к go, если вы хотите сэкономить память (и это действительно не так медленно). Кроме того, вы можете напрямую go из одного теста в c матрицу вывода с np.bincount . Я думаю, что этот метод будет примерно таким же быстрым, как ваш, и он будет использовать значительно меньше памяти для сравнения.

import numpy as np
c = np.empty(a.shape, dtype=int)
for i in range(a.shape[0]):
    test_one_vector = (a[i,:]==b).sum(axis=1)
    c[i,:] = np.bincount(test_one_vector, minlength=a.shape[1])

Небольшая заметка, если вы действительно имеете дело с числами с плавающей запятой в a и b, вам следует рассмотреть возможность отказа от проверки равенства (==) в пользу проверки близости, например, np .isclose

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...