Есть ли функция numpy или какой-то способ улучшить следующие вложенные циклы for?

#python

Вопрос:

Я пытаюсь вычислить матрицу корреляции, но временная сложность действительно высока даже при использовании numpy ndarrays, код выглядит следующим образом:

 def coranking(self, HD: np.ndarray, LD: np.ndarray):
    try:
        if HD.size != LD.size:
            raise CorankingException("matrices hdpd and ldpd do not have the same sizes")

        nbr = HD.shape[0]
        sss = HD.shape[1]

        self.ndx1 = np.transpose(np.argsort(HD, axis=1))
        self.ndx2 = np.transpose(np.argsort(LD, axis=1))

        self.ndx4 = np.zeros((nbr, sss), dtype=np.uint32)

        print(sss)
        print(nbr)

        start = timer()
        for j in range(sss):
            for i in range(nbr):
                self.ndx4[self.ndx2[i, j], j] = i
        print(f"FIRST O(N^2) process =>, {timer() - start:0.4f} sec")

        del self.ndx2

        c = np.zeros((nbr, sss), dtype=np.uint32)

        start = timer()
        for j in range(sss):
            for i in range(nbr):
                h = self.ndx4[self.ndx1[i, j], j]
                c[i, h]  = 1
        print(f"SECOND O(N^2) process =>, {timer() - start:0.4f} sec")
        del self.ndx1, self.ndx4

        c = np.delete(c, 0, axis=0)
        c = np.delete(c, 0, axis=1)

        return c
 

Тем вложенным циклам for требуется много времени для выполнения, на моей машине для первого требуется почти 8 секунд, а для второго-80 секунд, я пытался использовать модуль многопроцессорной обработки, но я понятия не имею, как его реализовать в этом случае, как я могу снизить время сложности этого алгоритма?

Комментарии:

1. Вы смотрели на индексацию векторов/массивов? Я думаю, что это решило бы некоторые из ваших проблем: jakevdp.github.io/PythonDataScienceHandbook/…

2. «но временная сложность действительно высока даже при использовании numpy ndarrays» массивы numpy, как правило, никогда не имеют лучшей временной сложности . На самом деле, для многих вещей это хуже

3. Почему try рядом с верхом есть свободное место, без ан except ?

4. @jhso Спасибо, я прочитал некоторые части этой ссылки, и это действительно ускоряет алгоритм

Ответ №1:

Я выясняю, как сделать это быстрее, вместо того, чтобы

 for j in range(sss):
    for i in range(nbr):
        self.ndx4[self.ndx2[i, j], j] = i
 

и это

 for j in range(sss):
    for i in range(nbr):
        h = self.ndx4[self.ndx1[i, j], j]
        c[i, h]  = 1
 

Я делаю следующее:

 range_nbr = range(nbr)  # nbr is the number of points of the data input
for j in range(sss):
    self.ndx4[self.ndx2[range_nbr, j], j] = range_nbr
 

И для второго вложенного цикла for

 for j in range(sss):
    h = self.ndx4[self.ndx1[range_nbr, j], j]
    c[range_nbr, h]  = nbr
 

в прошлом выполнение алгоритма занимало почти 80 секунд, при этом оно сократилось до 13 секунд, и я думаю, что реализация многопроцессорной обработки может быть быстрее