Python Forum
Make dual vector dot-product more efficient
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Make dual vector dot-product more efficient
#1
I have a dot product calculating weighted means, and is applied to two columns in a list with the measured values in column 5 and 6:

# calculate weighted values in sequence
for i in range(len(temperatures)-len(weights)):
  temperatures[i].append(sum([weights[j]*temperatures[i+j][5] for j in range(len(weights))]))
  temperatures[i].append(sum([weights[j]*temperatures[i+j][6] for j in range(len(weights))]))
The calculation performs a running dot-product, appending both values to the list temperatures. The list of temperature samples is far larger than the list of weights, hence the correction of subtracting len(weights) at the end of the main loop.
This traverses the list of weights twice, which is inefficient and degrades performance. How could this be done in a more pythonic way?

I also have concerns about the main loop because of the correction with len(weights). Would this be considered more pythonic?:

# calculate weighted values in sequence
for i in range(len(temperatures)):
   try:
      # insert weighted calculation here
   except:
      # do nothing, because array out of bounds
Reply
#2
Look into numpy module, there´s a .dot() method to calculate this extremly fast
Reply
#3
Thank you for your response, but perhaps I should have mentioned that this is a newbie question. I am looking for a solution that helps me understand the syntax and idiom of Python better, and without having to resort to other libraries.
Reply
#4
It seems clear to me that you are computing discrete convolutions of numerical arrays. The best way to do this is probably to use numpy. Consider the following code comparing a computation with a list to a computation with a numpy array
import numpy as np

def main():
    T = [3., 1., 5., 7., 9., 2., -1.]
    W = [0.2, -0.1, 0.3]
    
    R = [sum(W[j] * T[i + j] for j in range(len(W)))
         for i in range(len(T) - len(W)+ 1)]
    print(R)
    
    t = np.array(T)
    w = np.array(W)
    r = np.convolve(t, w[::-1], 'valid')
    print(r)


if __name__ == '__main__':
    main()
Output:
[2.0, 1.8, 2.9999999999999996, 1.1, 1.3] [ 2. 1.8 3. 1.1 1.3]
Concerning execution time, I compared with the timeit module and for an array T of size 21 and W of size 6, the numpy version is already more than 10 x faster than the list version. This difference will grow much more with larger arrays.

Let us not forget to conclude with this famous quote from The Art of Computer Programming

Donald Knuth Wrote:“The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.”
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Create dual folder on different path/drive based on the date agmoraojr 2 445 Jan-21-2024, 10:02 AM
Last Post: snippsat
  A more efficient code titanif 2 494 Oct-17-2023, 02:07 PM
Last Post: deanhystad
  Cleaning my code to make it more efficient BSDevo 13 1,372 Sep-27-2023, 10:39 PM
Last Post: BSDevo
Information Showing trendline formula in a table per product Carlossxx 0 663 May-03-2023, 08:34 AM
Last Post: Carlossxx
  Making a function more efficient CatorCanulis 9 1,838 Oct-06-2022, 07:47 AM
Last Post: DPaul
  How would you (as an python expert) make this code more efficient/simple coder_sw99 3 1,807 Feb-21-2022, 10:52 AM
Last Post: Gribouillis
Question How to understand the vector/direction mason321 0 1,113 Dec-14-2021, 10:57 PM
Last Post: mason321
  How to find vector of a 3D plot mason321 0 1,017 Nov-13-2021, 05:05 PM
Last Post: mason321
  How to add product details in exe generated by pyinstaller arex786 1 8,479 Oct-10-2021, 11:00 AM
Last Post: Sran012
  How do I make a symmetric matrix from a column vector? leocsmith 3 3,687 Mar-30-2021, 10:17 AM
Last Post: leocsmith

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020