4

I tried to calculate the cumulative products for my list elements as below. In my list, each element is two-dimensional list:

import numpy as np

Orig_list = [[[1,2,3], [4,5,6], [7,8,9]], [[11,3,4], [22, 4, 5], [22, 5, 1]], [[7,6,7], [2,5,6], [4,6,7]], [[234, 56, 22], [44, 66, 33], [44, 66, 33]]]

Result_list = [np.nan] * 4
Result_list[0] = Orig_list[0]
for i in range(1, len(Result_list)):
  Result_list[i] = (np.array(Result_list[i - 1]) @ np.array(Orig_list[i])).tolist()

The above works, but I am looking for cleaner and faster implementation as my original list is fairly big and each element is also a large two-dimensional list.

Is there anything like a more direct cumulative product function/method for above calculation?

4
  • @furas If I understand correctly, cumprod produces elementwise multiplication. However, OP asks for matrix-matrix multiplication (the inputs are 3×3 matrices which are not to be accumulated with an element-wise product but with a matrix-matrix product, which is why they use the @ operator). Commented Oct 21 at 13:33
  • @simon I was going to ask OP for showing result which OP gets - to see if this "cumulative product" produces normal cumprod :). Meanwhile I run this code and now I see it needs something different. So pandas.DataFrame.cumprod (and numpy.cumprod) seems useless for this. Commented Oct 21 at 13:37
  • @furas You can see their desired result from Result_list after their for loop (which produces, as mentioned, the desired result, but which, being a loopy solution, they want to avoid) Commented Oct 21 at 13:38
  • 1
    @simon without running code I don't see what this code is really doing. But meanwhile I ran it and saw it :) Commented Oct 21 at 13:41

1 Answer 1

3

You could use itertools.accumulate:

from itertools import accumulate

out = np.array(list(accumulate(Orig_list, np.dot)))

Output:

array([[[      1,       2,       3],
        [      4,       5,       6],
        [      7,       8,       9]],

       [[    121,      26,      17],
        [    286,      62,      47],
        [    451,      98,      77]],

       [[    967,     958,    1122],
        [   2314,    2308,    2703],
        [   3661,    3658,    4284]],

       [[ 317798,  191432,   89914],
        [ 761960,  460310,  216271],
        [1206122,  729188,  342628]]])

If you only care about the final result, go with numpy.linalg.multi_dot:

out = np.linalg.multi_dot(Orig_list)

Output:

array([[ 317798,  191432,   89914],
       [ 761960,  460310,  216271],
       [1206122,  729188,  342628]])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.