6

I have the following dataframe of returns

ret
Out[3]: 
Symbol            FX      OGDC       PIB       WTI
Date                                              
2010-03-02  0.000443  0.006928  0.000000  0.012375
2010-03-03 -0.000690 -0.007873  0.000171  0.014824
2010-03-04 -0.001354  0.001545  0.000007 -0.008195
2010-03-05 -0.001578  0.008796 -0.000164  0.015955

And the following weights for each symbol:

df3
Out[4]: 
  Symbol    Weight
0   OGDC  0.182022
1    WTI  0.534814
2     FX  0.131243
3    PIB  0.151921

I am trying to get a weighted return for each day and tried:

port_ret = ret.dot(df3)

but I get the following error message:

ValueError: matrices are not aligned

My objective is to have a weighted return for each date such that, for example 2010-03-02 would be as follows:

weighted_ret = 0.000443*.131243+.006928*.182022+0.000*0.151921+0.012375*.534814 = 0.007937512

I am not sure why I am getting this error but would be very happy for an alternative solution to the weighted return

albert
  • 8,285
  • 3
  • 19
  • 32
John
  • 531
  • 1
  • 8
  • 23

3 Answers3

5

You have two columns in your weight matrix:

df3.shape
Out[38]: (4, 2)

Set the index to Symbol on that matrix to get the proper dot:

ret.dot(df3.set_index('Symbol'))
Out[39]:
              Weight
Date
2010-03-02  0.007938
2010-03-03  0.006430
2010-03-04 -0.004278
2010-03-05  0.009902
Zeugma
  • 31,231
  • 9
  • 69
  • 81
4

For a dot product of dataframe dfA by dataframe dfB, the column names of dfA must coincide with the index of dfB, otherwise you'll get the error 'ValueError: matrices are not aligned'

dfA = pd.DataFrame( data = [[1, 2], [3, 4], [5, 6]], columns=['one', 'two'])
dfB = pd.DataFrame( data = [[1, 2, 3], [4, 5, 6]], index=['one', 'two'])
dfA.dot(dfB)
-1

Check the shape of the matrices you're calling the dot product on. The dot product of matrices A.dot(B) can be computed only if second axis of A is the same size as first axis of B.
In your example you have additional column with date, that ruins your computation. You should just get rid of it in your computation. Try running port_ret = ret[:,1:].dot(df3[1:]) and check if it produces the result you desire.
For future cases, use numpy.shape() function to debug matrix calculations, it is really helpful tool.

fulaphex
  • 2,879
  • 3
  • 19
  • 26
  • when I run port_ret = ret[:,1:].dot(df3[1:]) I get TypeError: unhashable type: 'slice' – John Sep 05 '16 at 01:56
  • What does `shape(ret)` and `shape(df3)` return? At first I've thought, that those are numpy arrays, but now I see it's pandas – fulaphex Sep 05 '16 at 02:04
  • In[15] np.shape(df3) Out[15]: (4, 2) In[17] np.shape(ret) Out[17]: (4, 4) – John Sep 05 '16 at 02:07
  • so obviously they are of different sizes, is there a "pandas" approach that will accomplish the same objective? – John Sep 05 '16 at 02:09