Как сделать понимание списка быстрее? - PullRequest
0 голосов
/ 02 мая 2020

Есть ли вообще что-нибудь, что я мог бы использовать для ускорения понимания вложенного списка (иногда условного)?

Я думал о numpy или транспонировании (но как?), Но может быть что-то, что я видел.

Примеры:

nextInt = 1
winPoints  = [[max(upSlice[:i])  for i in range(nextInt,len(upSlice)+1)] for upSlice in ppValues]```

или

winningRatio =[ [1 if ratioUp >ratioDown  else 0 if (ratioDown>ratioUp) else
                1 if (pointsUp>pointsDown) else 0 if (pointsDown>pointsUp) else 1   
                for ratioUp,ratioDown,pointsUp,pointsDown                  in  zip(ratioUpSlice,ratioDownSlice,pointsUpSlice,pointsDownSlice)] 
                for ratioUpSlice,ratioDownSlice,pointsUpSlice,pointsDownSlice in  zip(ratios_Up,ratios_Down, pointsUpSlices,pointsDownSlices)]

(все фрагменты во вложенном списке НЕ имеют одинаковую длину)

1 Ответ

0 голосов
/ 03 мая 2020

Я предполагаю, ppValues - это двумерный список чисел?

Как правило, для ускорения работы алгоритмов вы хотите избавиться от любых избыточных вычислений. Например, в вашем первом фрагменте кода часть max(upSlice[:i]) выполняется (n * m) раз и выполняет приблизительно ((n ^ 2) / 2 * m) вычисления, где (n) - длина внутреннего списка и m - длина внешнего списка. И выполнение вычисляет максимум одного и того же среза (за исключением 1 дополнительного элемента), что является множеством ненужных сравнений.

Чтобы ускорить его, мы можем использовать динамическое c программирование, где мы строим Массив slice_max такой, что элемент с индексом i равен max(upSlice[:i]). И мы можем сделать это эффективно, используя прошлые вычисления, поскольку элемент с индексом i равен максимуму двух элементов, max(slice_max[i-1], upSlice[i]), который является только одним вычислением.

Вот простая реализация динамического c версия программирования:

def get_slice_max(arr, start):
    result = [max(arr[:start])]
    for i in range(start, len(arr)):
        result.append(max(result[-1], arr[i]))
    return result
winPoints  = [get_slice_max(upSlice, nextInt) for upSlice in ppValues]

Вот сравнение:

Генерация данных

# generate fake data
np.random.seed(42)
# the variable length of inner lists: [7270,  860, 5390, ..., 1389, 4276, 1249]
inner_sizes = np.random.randint(low=1, high=1000, size=10000)
ppValues = [np.random.randint(1000, size=i) for i in inner_sizes]
# ppValues contains 10000 lists, each having 1 to 1000 elements, each element is a number between 1 to 10000

Ваша версия

nextInt=1
winPoints  = [[max(upSlice[:i])  for i in range(nextInt,len(upSlice)+1)] for upSlice in ppValues]

------------------
Wall time: 2min 36s

Simple Dynami c Версия программирования

def get_slice_max(arr, start):
    result = [max(arr[:start])]
    for i in range(start, len(arr)):
        result.append(max(result[-1], arr[i]))
    return result
winPoints  = [get_slice_max(upSlice, nextInt) for upSlice in ppValues]

-----------------
Wall time: 1.79 s

Вы можете увидеть значительное улучшение от 2,5 минут до <2 секунд. </p>

Что касается второго примера, вы не предоставили достаточно контекста, чтобы попытаться решить эту проблему.

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