Class #9 – More Lists and Numpy Arrays

_images/hypercube3.png

Higher Dimensions

Activity

Let’s say we have a list:

>>> a = ['a','b','c']

Questions:

  • What is the length of this list?

  • What is the type of the things in this list?

  • What do I type to get 'a' printed out?

Answer these, and then test it in code.

Activity

OK cool, what if I do this:

>>> a = ['a','b','c']
>>> b = [a]

Questions:

  • What is the length of this list?

  • What is the type of the things in this list?

  • What do I type to get 'a' printed out?

Answer these, and then test it in code.

Activity

What if I do this:

>>> a = ['a','b','c']
>>> b = [a, ['d', 'e', 'f']]

Questions:

  • What is the length of this list?

  • What is the type of the things in this list?

  • What do I type to get 'a' printed out? Can you think of how you could do it two ways?

Answer these, and then test it in code.

Activity

Here’s a weird one:

>>> a = ['a','b','c']
>>> b = [a, a]

Questions:

  • What is the length of this list?

  • What is the type of the things in this list?

  • What do I type to get 'a' printed out?

  • What happens if I write this b[0][0] = 'Z'?

Answer these, and then test it in code.

Activity

Last one, I swear:

>>> a = ['a','b','c']
>>> b = [a, ['d', 'e', 'f']]
>>> c = [b, ['g', 'h', 'i']]

Questions:

  • What is the length of this list?

  • What is the type of the things in this list?

  • What do I type to get 'a' printed out?

Answer these, and then test it in code.

Numpy Arrays

Warning

Numpy arrays are a little different than classic arrays. Nothing too much to worry about, but just be aware.

  • The list was our first data structure.

  • Now we’re going to meet a similar, but slightly different, one: the numpy array

  • Let’s get started:

    >>> import numpy
    >>> a = numpy.array([5,4,2])
    >>> print(a)
    [5 4 2]
    
  • Looks a lot like a list, doesn’t it?

  • Can we manipulate it like a list?

    >>> print(a[0])
    5
    
    >>> print(a[1])
    4
    
  • We can definitely index it, the same as a list.

  • I wonder if arrays are mutable?

    >>> a[1] = 7
    >>> print(a)
    [5 7 2]
    
  • Yes, arrays are mutable.

  • With lists, I could mix types in a single list. Like this:

    >>> l = [5,4,3]
    >>> l[2] = 'walrus'
    >>> print(l)
    [5, 4, 'walrus']
    
  • Can I do that with arrays?

    >>> a = numpy.array([5,4,2])
    >>> a[2] = 'walrus'
    ValueError: invalid literal for long() with base 10: 'walrus'
    
  • Ah ha! We found a way in which arrays are different.

  • Lists are just collections of stuff. Any old stuff. Each element can be of a different type.

  • In an array, every element must have the same type!

Activity

Create two arrays of integers, each having the same number of elements.

What mathematical operations can you do on the arrays? (+,-,*,/).

What happens if you try to perform the operations on arrays of different sizes?

How does + work differently on arrays than lists?

Numpy array object attributes and methods

  • Remember how I showed you how objects, like strings, had some methods attached to them?

  • Objects can also have attributes

  • We can ask numpy arrays what type the items in an array have like this:

    >>> a.dtype
    dtype('int32')
    
  • If you want to see all the attributes and methods your array has you can type a. (a dot) and then press the [Tab] key.
    • Ones with parentheses are methods

    • Ones with no parentheses are attributes

  • That’s a lot of methods and attributes!

  • Some of those are things like dtype that store information about the state of the object (attributes).

  • Some are special functions (methods) that can only be applied to that object

    >>> a = numpy.array([5, 4, 2])
    >>> print(a.sum())
    11
    
    >>> print(a.max())
    5
    
    >>> print(a.mean())
    3.6666666666666665
    
  • When a function (method) appears after a . , that function is automatically applied to the object appearing before the .
    • These special functions built in to objects can also take parameters.

  • For example, we can change the types of the elements of our array:

    >>> b = a.astype(float)
    >>> print(b)
    [ 5.,  4.,  2.]
    

Making numpy arrays bigger

  • With lists, we could always append items to make them bigger

    >>> a = [1, 2, 3]
    >>> a.append(5)
    >>> print(a)
    [1, 2, 3, 5]
    
  • Or even concatenate two lists together like this

    >>> a = [1,2,3] + [5]
    >>> print(a)
    [1, 2, 3, 5]
    
  • Arrays are meant to have fixed size.

  • Why do you think this is?

  • If you really, really, want to make an array bigger… you can’t.

  • You can however, make a new array that is bigger using numpy.append():

    >>> a = numpy.array([1,2,3,4])
    >>> print(a)
    [1, 2, 3, 4]
    
    >>> b = numpy.append(a,5)
    >>> print(a)
    [1, 2, 3, 4]
    
    >>> print(b)
    [1, 2, 3, 4, 5]
    
  • Note that .append(...) here is a FUNCTION, not a method.
    • What is the input parameters and types here?

    • What does this function return?

  • Note carefully that numpy.append() did not change a. It created a new array, b.

  • This is also kinda’ like strings. Remember, we had to make copies of the string to make any changes?

Activity

Create an array of 4 integers.

Create a new, bigger, array by appending the integer 7 on to your array.

Create another new array by appending the string 'walrus'.

Did that last one work? What happened?

Flexibility vs Power

  • Arrays are less flexible than lists:
    • We can’t change their size

    • They can only store data of a single type

  • But… it is this very lack of flexibility that lets us do all sorts of cool stuff (eg. .sum())

Activity

How would you implement .sum() for a list?

Higher dimensions

  • Like lists, numpy arrays generalize to higher dimensions.

  • Let’s create a 2D array:

    >>> a=numpy.array([[1,2,3],[4,5,6],[7,8,9]])
    >>> print(a)
    [[1 2 3]
     [4 5 6]
     [7 8 9]]
    
  • Note the format in our call to numpy.array. A list of lists.

  • Each row of the array gets its own list.

  • As long as two 2D arrays have the same shape, you can do arithmetic on them, just like 1D arrays.

  • How do we check the shape of an array?
    • .shape attribute

    >>> print(a.shape)
    (3, 3)
    

Activity

Create a 4x4 array. Verify that it has shape (4,4).

You’ve changed your mind. The array should actually be 2x8. reshape your 4x4 array in to a 2x8 array without recreating it from scratch.

Verify that the reshaped array is (2,8).

Finally flatten your 2D array into a 1D array.

Starting points

  • Sometimes you want an array of shape (n,m) that contains all zeros:

    >>> # The extra parentheses are important
    >>> a = numpy.zeros((n,m))
    
  • Guess what numpy.ones() does?

  • How about numpy.eye()?

Slicing

  • We’ve already seen that you can index arrays like lists (and strings)

  • Likewise, you can use Python’s powerful slicing on arrays

Activity

Create an array arr = numpy.array([0,1,2,3,4,5,6,7]). Using a single command
  1. Print the first 3 elements

  2. Print the last 3 elements

  3. Print the even elements of arr

  • Slicing works for higher dimensional arrays, too. For example:

    >>> a = numpy.arange(25).reshape(5,5)
    >>> print(a)
    [[ 0  1  2  3  4]
     [ 5  6  7  8  9]
     [10 11 12 13 14]
     [15 16 17 18 19]
     [20 21 22 23 24]]
    
    >>> print(a[0:2,1:4])
    [[1 2 3]
     [6 7 8]]
    
  • Note the use of numpy.arange which works like range but returns an array.

  • If you want a whole column/row/etc, you can use a plain : as the index. For example, if I wanted to pull out every row of the first two columns:

    >>> print a[:,0:2]
    [[ 0  1]
     [ 5  6]
     [10 11]
     [15 16]
     [20 21]]
    

Activity

Modify the previous command to print all of the columns of the first two rows.

For loops

  • If for loops work for lists, do you think they’ll work for arrays?

Activity

Write a function printeach(arr) that uses a for loop to print each element of an array that is passed in as a parameter.

Test it on a 1D array.

Now try a 2D array.

If you’re feeling bold, how about a 3D array?

For next class