Как переписать двойной цикл в Numpy, чтобы сэкономить время выполнения? - PullRequest
0 голосов
/ 31 января 2019

Я хотел бы создать колоду карт наиболее эффективным способом.Это простое решение с двойными циклами и стандартными списками:

card = []
for figure in range(2, 15):
    for suite in [1, 2, 3, 4]:
        card = [figure, suite]
        self.cards.append(card)

Этот код будет выполняться миллионы раз, поэтому я хотел бы оптимизировать его с помощью Numpy.

EDIT1: Я дажеподумайте, не будет ли самая быстрая запись всех возможностей и их помещение в массив ..

1 Ответ

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

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

Сначала ваш код, который я исправил, чтобы сделать работоспособным:

cards = []
for figure in range(2, 15):
    for suite in [1, 2, 3, 4]:
        card = [figure, suite]
        cards.append(card)
# 8.04 µs ± 27.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Итак, 8,04 микросекунды - самое время!Использование numpy.mgrid:

import numpy as np
cards = np.mgrid[1:5, 2:15]
# 20.5 µs ± 320 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Удивительно намного медленнее.Интересно, не настроено ли что-нибудь идеально в моей системе для NumPy.Я все еще рекомендую попробовать его в своей системе (используйте волшебство ячейки %%timeit в блокноте Jupyter для легкого профилирования).

Далее используйте itertools.product:

import itertools as it
figures = range(2, 15)
suits = [1, 2, 3, 4]
cards = list(it.product(suits, figures))
# 2.5 µs ± 27.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Быстрее!И лучшая новость заключается в том, что it.product() возвращает итератор вместо создания списка при вызове, поэтому, если вам не нужен фактический список карт на более поздний срок, вы можете отложить создание списка и просто передать итератор.Создание итератора является самым быстрым на данный момент:

cards_it = it.product(suits, figures)  # notice no 'list'
# 479 ns ± 9.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Это в 5-10 раз быстрее, чем что-либо еще!

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