One index: one item
closes[1]It gives 187.2 · one number, not a list
The number in the brackets is a position, counted from 0. You get the item itself, not a list.
Data Science and Advanced Programming · Session 5
Lists first, then 2-D numpy arrays. Gold boxes are what the slice keeps.
Before you look at a result, say out loud which boxes you expect to turn gold. Then check. Every picture and every result on this page was produced by running the code.
Five closing prices, one per day:
closes = [190.5, 187.2, 193.8, 185.1, 191.4]closes[1]It gives 187.2 · one number, not a list
The number in the brackets is a position, counted from 0. You get the item itself, not a list.
closes[1:4]It gives [187.2, 193.8, 185.1] · a list of 3
Think of start and stop as cuts BETWEEN the boxes. You keep what lies between the cuts: boxes 1, 2 and 3. Box 4 is not included.
closes[:2]It gives [190.5, 187.2] · a list of 2
No start means: cut at the very left. [:2] is the first two items. Length = stop − start = 2.
closes[-2:]It gives [185.1, 191.4] · a list of 2
−1 is the last box, −2 the one before it. [-2:] is the last two items, however long the list is.
closes[::2]It gives [190.5, 193.8, 191.4] · a list of 3
start:stop:step. With no start and no stop the slice covers the whole list; step 2 takes every second box. The small numbers show the order.
closes[::-1]It gives [191.4, 185.1, 193.8, 187.2, 190.5] · a list of 5
A negative step walks from the right to the left. [::-1] is the whole list, reversed. Look at the small numbers: the last box comes first.
closes[1]It gives 187.2 · one number, not a list
closes[1:2]It gives [187.2] · a list of 1
An index gives the item. A slice ALWAYS gives a list, even a list of one. That difference comes back in numpy as a difference in shape.
The price grid from the lecture: one row per position, one column per day. In prices[rows, columns], each side of the comma is sliced on its own.
prices = np.array([[185.0, 188.2, 190.5], # AAPL
[104.1, 103.0, 102.3], # NESN
[505.0, 509.9, 512.0]]) # VOOprices[1]It gives [104.1, 103.0, 102.3] · shape (3,)
One number in the brackets picks a row: NESN. The row has 3 prices, so the shape is (3,): one dimension.
: for every rowprices[:, -1]It gives [190.5, 102.3, 512.0] · shape (3,)
: before the comma means every row. −1 after it is the last day. You get the last price of each position, again shape (3,).
prices[1, 2]It gives 102.3 · shape ()
Row 1, column 2. Two single numbers remove both dimensions: one number, shape ().
prices[:2, 1:]It gives [[188.2, 190.5], [103.0, 102.3]] · shape (2, 2)
Rows up to 2 (AAPL, NESN), columns from 1 on (days 1 and 2). Slices keep their dimension, so the result is still a table: (2, 2).
prices[:, [0, 2]]It gives [[185.0, 190.5], [104.1, 102.3], [505.0, 512.0]] · shape (3, 2)
A LIST in a position picks exactly those columns, here the first and the last day. All rows, two columns: (3, 2).
prices[1:2]It gives [[104.1, 103.0, 102.3]] · shape (1, 3)
Same cells as prices[1], but a slice keeps the dimension: a table with one row, shape (1, 3), not (3,).
Count what is in the brackets. Every single number removes a dimension. Every slice (with :) or list keeps one. prices[1] → (3,) · prices[1:2] → (1, 3) · prices[1, 2] → () · prices[:2, 1:] → (2, 2). When numpy surprises you, print .shape first.
Each day divided by the day before. The two slices have the same shape, so numpy divides cell by cell.
prices[:, 1:] # days 1, 2prices[:, :-1] # days 0, 1returns = prices[:, 1:] / prices[:, :-1] - 1It gives [[0.0173, 0.0122], [-0.0106, -0.0068], [0.0097, 0.0041]] (rounded to 4) · shape (3, 2)
Three days give two returns per position, so the shape is (3, 2).