You want to gradually transform this from the use of lists and loops to the use of arrays and broadcasting, first capturing the simplest and / or most important parts in time until they become fast enough.
The first step is not to repeat this zip(*list2) again and again (especially if it's Python 2.x). While we are doing this, we can save it in an array and do the same with list1 - you can still list1 over them at the moment. So:
array1 = np.array(list1) array2 = np.array(zip(*list2)) # β¦ for elem in array1: # β¦ for elem2 in array2:
This will not speed up work on my machine, it will take from 14.1 seconds to 12.9, but it gives us the opportunity to get started.
You should also remove the double calculation sum(list3) :
sum_list3 = sum(list3) sum_list3 = sum_list3 if sum_list3>0. else 1e-06
Meanwhile, itβs a little strange that you want value <= 0 to go to 1e-6 , but leave 0 < value < 1e-6 alone. Is this really intentional? If not, you can fix this and simplify the code at the same time by simply doing this:
sum_list3 = max(array3.sum(), 1e-06)
Now broadcast mailings A and B :
And that forces us from 12.9 seconds to 0.12. You can take it one step further by also passing along array1 and replacing list4 with a pre-allocated array, etc., but this is probably fast enough.
source share