оптимизировать numpy l oop используя функциональный подход - PullRequest
1 голос
/ 03 марта 2020

Уважаемые, я новичок в Python / Numpy, хотел бы знать, как устранить петли и иметь лучшую производительность для приведенного ниже кода, для симуляции Монте-Карло.

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import pandas as pd

iterations = 3
months = 12
group_size = 5
exit_factor = 0.2
membership_fee = 2


# join delay [periods]
join_delay = np.random.triangular(left=0, mode=4, right=7,
                                  size=(iterations, group_size)).astype(int)
# exit [number of users]
exit_users = np.random.triangular(left=5, mode=10, right=20, 
                                  size=(months, iterations)).astype(int)

sim_table = np.zeros(shape = (iterations, group_size, months), dtype = 'int')
print(join_delay)
for j in range (0, iterations):
  for i in range(0, group_size):
    sim_table[j,i,join_delay[j,i]] = 200
print(sim_table)

1 Ответ

3 голосов
/ 03 марта 2020

Используя расширенное индексирование и широковещательную рассылку, вы можете присвоить значение 200 одновременно всем индексам вместо использования neseted для l oop:

sim_table[np.arange(iterations)[:, np.newaxis],
          np.arange(group_size)[np.newaxis, :],
          join_delay] = 200

Таблица, показывающая увеличение скорости:

#              iterations * group_size
#                    15 |      150 |      1500 |    15000 | 150000   | 15000000
# loop [sec]:  3.00e-05 | 1.67e-04 |  1.58e-03 | 1.52e-02 | 6.07e-02 | 4.73e-00
# numpy [sec]: 4.19e-05 | 4.43e-05 |  7.05e-05 | 2.90e-04 | 1.49e-03 | 1.24e-01
# relative:         0.7 |      3.8 |      22.4 |     52.4 |     40.7 |     38.1
...