1

So I have an array of 5 integers v and another of 10 integers v. I have a 5 by 10 matrix P that I would want to fill so that (P)ij = v[i] + u[j]

I tried:

P = np.empty((len(asset_grid),len(asset_grid)))
for i in range(asset_grid):
    for j in range(asset_grid):
        P[i,j] = asset_grid[i] + asset_grid[j]

but it gives me an error

TypeError: only integer arrays with one element can be converted to an index

How should I be able to do this in Python. I apologize if my approach is too naive, I am used to Matlab and now slowly learning Python. Any help is appreciated.

5
  • I presume you want (need) to do this in numpy? Commented Aug 30, 2017 at 17:51
  • yes, in numpy would be good Commented Aug 30, 2017 at 17:52
  • 2
    So, is asset_grid an array or scalar? If array, range(asset_grid) doesn't make sense. Commented Aug 30, 2017 at 17:55
  • 3
    You can simply use broadcasting : asset_grid[:,None] + asset_grid or np.add.outer(asset_grid, asset_grid). Commented Aug 30, 2017 at 17:58
  • stackoverflow.com/a/40664794/8427155 Commented Aug 30, 2017 at 18:14

1 Answer 1

2

Broadcasting is what you want to do. Although for small arrays such as yours, it doesn't make a difference, it makes a significant difference with larger arrays:

>>> arr1 = np.arange(5)
>>> arr2 = np.arange(10,20)
>>> arr1[:,None] + arr2
array([[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
       [12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
       [13, 14, 15, 16, 17, 18, 19, 20, 21, 22],
       [14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])

Generally with numpy you want to avoid iteration over rows and columns and use vectorized/broadcasted operations. This is where speed improvements actually come from.

So, elaborating based on your comment:

Say P_ij is ith element of x raised to the 4th power minus jth element of y raised to 2nd power

In general, Python supports most arithmetical operations you would want in a vectorized way, using the usual Python operators:

>>> arr1[:, None]**4 - arr2**2
array([[-100, -121, -144, -169, -196, -225, -256, -289, -324, -361],
       [ -99, -120, -143, -168, -195, -224, -255, -288, -323, -360],
       [ -84, -105, -128, -153, -180, -209, -240, -273, -308, -345],
       [ -19,  -40,  -63,  -88, -115, -144, -175, -208, -243, -280],
       [ 156,  135,  112,   87,   60,   31,    0,  -33,  -68, -105]])
Sign up to request clarification or add additional context in comments.

6 Comments

Great. What if instead of adding I wanted to do some other kind of operation. Say P_ij is ith element of x raised to the 4th power minus jth element of y raised to 2nd power
@mathemagician added an example. You should start practicing vectorizing your code. It's not always straight-forward, but for these simple examples it's easy as pie. You can always ask a question if a particular attempt stumps you - we've got a couple of numpy magicians on here...
Haha, awesome. What if my question was about filling a 3d matrix with say 4th power of ith element of x minus 3rd power of jth element of y plus 2nd power of lth element of z. Does this vectorization strategy generalize?
@mathemagician probably a good time to check out the docs. And this link is pretty good.
I tried arr1[:,:,None]*arr2[:,None]*arr3 and it didn't work. Am I able to go beyond 2 dimensions with this technique?
|

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.