choubix
choubix

Reputation: 59

Loop with 2 elements and a zip

A friend sent me a Jupyter notebook with the below code:

for stock_df, allo in zip((aapl, cisco, ibm, amzn), [.3,.2,.4,.1]):
    stock_df['Allocation'] = stock_df['NormedReturn']*allo

I understand the output as it creates a new column 'Allocation' in each dataframe 'aapl', 'cisco'... and applies weights to the Normed Returns. However, I do not understand the syntax enough that I could do it again by myself.

How does this for loop on 2 elements and the zip work please? (I thought that the elements had to be of similar length when zipping otherwise the output data would be truncated).

Upvotes: 1

Views: 188

Answers (2)

FatihAkici
FatihAkici

Reputation: 5109

This looks like a portfolio diversification kind of code. The aapl, cisco, ibm and amzn are DataFrames containing at least a NormedReturn field.

aapl = pd.DataFrame({'NormedReturn':[1,2,3]})
cisco = pd.DataFrame({'NormedReturn':[4,5,6]})
ibm = pd.DataFrame({'NormedReturn':[7,8,9]})
amzn = pd.DataFrame({'NormedReturn':[10,11,12]})

The DataFrames might as well be containing single values, like 'NormedReturn':[13], no problem.

Zip function zips together iterables. It is assigning the given allocation weights to these returns; .3 weigth to the aapl stock, .2 weight to the cisco stock, etc:

for stock_df, allo in zip((aapl, cisco, ibm, amzn), [.3,.2,.4,.1]):
    print stock_df, allo

Gives us the stock returns and the respective allocation weight:

   NormedReturn
0             1
1             2
2             3 0.3
   NormedReturn
0             4
1             5
2             6 0.2
   NormedReturn
0             7
1             8
2             9 0.4
   NormedReturn
0            10
1            11
2            12 0.1

Finally the assignment multiplies return series by the allocation weights:

for stock_df, allo in zip((aapl, cisco, ibm, amzn), [.3,.2,.4,.1]):
    stock_df['Allocation'] = stock_df['NormedReturn']*allo
    print stock_df

Gives your allocation, i.e. return*weight series:

   NormedReturn  Allocation
0             1         0.3
1             2         0.6
2             3         0.9
   NormedReturn  Allocation
0             4         0.8
1             5         1.0
2             6         1.2
   NormedReturn  Allocation
0             7         2.8
1             8         3.2
2             9         3.6
   NormedReturn  Allocation
0            10         1.0
1            11         1.1
2            12         1.2

I think after this your friend must be putting all of the NormedReturns and Allocations together, which is like your final portfolio return.

Upvotes: 1

Joe Iddon
Joe Iddon

Reputation: 20424

The key bit of Python syntax here is the zip() function.

From the documentation, we can see that this:

Returns an iterator of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables.

So it is passed iterables and 'zips' them together. This may be easier to see with an example:

>>> a = [1, 2, 3, 4]
>>> b = [9, 8, 7, 6]
>>> list(zip(a, b))
[(1, 9), (2, 8), (3, 7), (4, 6)]

So, in your code, this is being used alongside a method called 'tuple unpacking' which is just doing something like:

>>> i, j = 5, 6
>>> i
5
>>> j
6

This allows for clean code that will iterate over the tuples that are returned from the zip(). If you are still unsure on what the loop is doing, we could modify it to print the variables (for simplicity I also converted the variables passed into zip to strings):

for stock_df, allo in zip(('aapl', 'cisco', 'ibm', 'amzn'), [.3,.2,.4,.1]):
    print(stock_df, allo)

which you can see from the output gives what we expected:

aapl 0.3
cisco 0.2
ibm 0.4
amzn 0.1

I hope that clears up the code for you, it seems from how you asked the question that you already know how these variables are actually being dealt with in the loop so I won't go into that.

Upvotes: 2

Related Questions