2

I have a numpy array of values, and a list of scaling factors which I want to scale each value in the array by, down each column

values = [[ 0, 1, 2, 3 ],
          [ 1, 1, 4, 3 ],
          [ 2, 1, 6, 3 ],
          [ 3, 1, 8, 3 ]]
ls_alloc = [ 0.1, 0.4, 0.3, 0.2]

# convert values into numpy array
import numpy as np
na_values = np.array(values, dtype=float)

Edit: To clarify:

na_values can is a 2-dimensional array of stock cumulative returns (ie: normalised to day 1), where each row represents a date, and each column a stock. The data is returned as an array for each date.

I want to now scale each stock's cumulative return by its allocation in the portfolio. So for each date (ie: each row of ndarray values, apply the respective element from ls_alloc to the array element-wise)

# scale each value by its allocation
na_components = [ ls_alloc[i] * na_values[:,i] for i in range(len(ls_alloc)) ]

This does what I want, but I can't help but feel there must be a way to have numpy do this for me automatically?

That is, I feel:

na_components = [ ls_alloc[i] * na_values[:,i] for i in range(len(ls_alloc)) ]
# display na_components
na_components
[array([ 0. ,  0.1,  0.2,  0.3]), \
 array([ 0.4,  0.4,  0.4,  0.4]), \
 array([ 0.6,  1.2,  1.8,  2.4]), \
 array([ 0.6,  0.6,  0.6,  0.6])]

should be able to be expressed as something like:

tmp = np.multiply(na_values, ls_alloc)
# display tmp
tmp
array([[ 0. ,  0.4,  0.6,  0.6],
       [ 0.1,  0.4,  1.2,  0.6],
       [ 0.2,  0.4,  1.8,  0.6],
       [ 0.3,  0.4,  2.4,  0.6]])

Is there a numpy function which will achieve what I want elegantly and succinctly?

Edit: I see that my first solution has transposed my data, such that I am returned a list of ndarrays. na_components[0] now gives an ndarray of the stock values for the first stock, 1 element per date.

The next step that I perform with na_components is to calculate the total cumulative return for the portfolio by summing each individual component

na_pfo_cum_ret = np.sum(na_components, axis=0)

This works with the list of individual stock return ndarrays.

2 Answers 2

5

That order seems a little odd to me, but IIUC, all you need to do is to transpose the result of multiplying na_values by array(ls_alloc):

>>> v
array([[ 0.,  1.,  2.,  3.],
       [ 1.,  1.,  4.,  3.],
       [ 2.,  1.,  6.,  3.],
       [ 3.,  1.,  8.,  3.]])
>>> a
array([ 0.1,  0.4,  0.3,  0.2])
>>> (v*a).T
array([[ 0. ,  0.1,  0.2,  0.3],
       [ 0.4,  0.4,  0.4,  0.4],
       [ 0.6,  1.2,  1.8,  2.4],
       [ 0.6,  0.6,  0.6,  0.6]])
Sign up to request clarification or add additional context in comments.

Comments

1

It's not completely clear to me what you want to do, but the answer is probably in Broadcasting rules. I think you want:

values = np.array( [[ 0, 1, 2, 3 ],
                    [ 1, 1, 4, 3 ],
                    [ 2, 1, 6, 3 ],
                    [ 3, 1, 8, 3 ]] )
ls_alloc = np.array([ 0.1, 0.4, 0.3, 0.2])

and either:

na_components = values * ls_alloc

or:

na_components = values * ls_alloc[:,np.newaxis]

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.