Numpy and Objects

CSCI 1012

Announcements

  • Homework 12 is due Friday, 25 Apr 11:55 PM
    • Extra five days, not a Sunday
  • Next week (4/21): Exam Review
  • Following week (4/28): Unit 2 Exam
  • Optional Final Exam is May 5 (5:20-7:20pm)

Unit 2 Exam

  • 28 Apr – 3:45-5:00 PM – 1957 E St. 213
  • In person, on paper:
    • Identical format to quizzes and Unit 1 Exam
  • Notes permitted:
    • 1 side of one page (8.5” \(\times\) 11” or A4)
    • Notes must be hand-written by you
      • Talk to us if this is a challenge

Final Exam (Optional)

  • 5 May – 5:20-7:20 PM – 1957 E St. 213
  • Identical format as quizzes and midterms
  • 1 side of one page of notes permitted
  • Maximum score: 70%
    • Replaces all quizzes/exams it is higher than
  • We will tell you in advance if you can take it
    • Fall 2024: c. 2/3 of class had B+ or better without final

How It Started

print("Hello world!")
Hello world!

How It’s Going

In-Class Exercises

  • File names:
    • ex1.py
    • ex2.py
    • ex3.py
  • Turn in on the submit server before the end of lecture for credit
  • Turn in one .zip with all the .py files
  • Unlimited attempts: we’ll provide solutions – pay attention!

Warm-Up

Write a function list_sum that takes two list arguments:

  • All elements of both lists will be numeric (int or float)

  • Return a new list that sums the argument lists, element-by-element

  • Assume both lists are of equal length, greater than 0

  • list_sum([0, 1], [2, 3]) returns list [2, 4]

  • list_sum([0, -1.0, 2.0], [1, 2, 3]) returns list [1, 1.0, 5.0]

Starter code:

ex1.py
def list_sum(L1, L2):
    L3 = L1 + L2 # this does not work!
    return L3

Submit as ex1.py

Collections

  • Lists are ordered collections
    • Items can be anything
A = [2, 3, 4, 5] # all ints
B = [0, 1, "A", False] # mix of int, str, bool
C = [{"B": "C"}, 2.1, [0, 1], ("okay",)] #dict, float, list, tuple
A.append("E")
print(A)
print([2, 3] + [1, 2])
[2, 3, 4, 5, 'E']
[2, 3, 1, 2]
  • Lists “designed” for sequential operations
    • append and concatenation

Libraries

  • We’ve seen math
import math
print(math.ceil(2.1))
3
  • math gives us functions
    • math.sqrt, math.ceil, math.floor, etc.
  • math also gives us a few constant values
    • math.pi, math.e (there are others)

Numpy

import numpy
X = numpy.array([2, 3, 4])
print(X)
[2 3 4]
  • Try this on your computer - if it doesn’t work
    • numpy included in visualizer
  • numpy (“numeric Python”) provides new objects
    • Objects collect data with functionality
    • Built-in objects: list, string, tuple
      • ints, floats, bools 🤔

Syntax

  • Dots are connectors
  • math.floor(2.1)
    • floor function associated with math
    • . in a float is just a decimal
  • 'Thank you.'.upper()
    • upper function associated with string 'Thank you.'
    • . in a string is just a period

as

Contrast:

import numpy
X = numpy.array([2, 3, 4])

vs.

import numpy as np
X = np.array([2, 3, 4])
  • as keyword used in imports
  • importing numpy as np literally just saves us some typing
  • Ubiquitous: in all documentation
    • Effectively mandatory

Numpy Arrays

import numpy as np

# list concatenation
Q = [2, 3, 4]
R = [1, 1, 2]
print("Lists:", Q + R)

# numpy addition
X = np.array([2, 3, 4])
Y = np.array([1, 1, 2])
print("Numpy arrays:", X + Y)
[2, 3, 4, 1, 1, 2]
[3 4 6]

Numpy Arrays (continued)

import numpy as np

# lists
Q = [0, 2, 3, 4]
print("Lists:", Q * 5)

# numpy
X = np.array([0, 2, 3, 4])
print("Numpy arrays:", X * 5)
Lists: [0, 2, 3, 4, 0, 2, 3, 4, 0, 2, 3, 4, 0, 2, 3, 4, 0, 2, 3, 4]
Numpy arrays: [ 0 10 15 20]

Numpy Arrays!

import numpy as np

X = np.array([0, 2, 3, 4])
Y = X
print(X[2])
X[2] = 1
print(X)
3
[0 2 1 4]

(in the visualizer)

  • Follows the same “rules” as lists and dicts
    • All are mutable objects

Numpy Arrays vs. Lists

import numpy as np

# lists
Q = [0, 2, 3, 4]
R = Q.append(5)
print("Q:", Q)
print("R:", R)



# numpy
X = np.array([0, 2, 3, 4])
Y = np.append(X, 5)
print("Array X:", X) # X is not changed!
print("Array Y:", Y)
Q: [0, 2, 3, 4, 5]
R: None
Array X: [0 2 3 4]
Array Y: [0 2 3 4 5]

Modifying Arrays

import numpy as np

Z = np.array([3, 1, 2, 1])
print("Initial Z:", Z)

Z.resize(6, refcheck=False) # in place
print("Resized Z:", Z)

W = Z.reshape(2, 3) # returns new array
print("Final Z:",Z)
print("W:\n", W)
Initial Z: [3 1 2 1]
Resized Z: [3 1 2 1 0 0]
Final Z: [3 1 2 1 0 0]
W:
 [[3 1 2]
 [1 0 0]]

More Array Methods

Z = np.zeros(6)
Y = np.ones(5)
print("Z:", Z)
print("Y:", Y)

X = np.append(Z, Y) # different from list append!
print("X:", X)
Z: [0. 0. 0. 0. 0. 0.]
Y: [1. 1. 1. 1. 1.]
X: [0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1.]

Exercise

Write a function array_sum that takes two (1D, numeric) numpy array arguments:

  • The arrays may be of unequal length
  • Return a new array that sums the arrays element-by-element
    • If the arrays are unequal, treat addition as with zero

Starter code:

ex2.py
def array_sum(A1, A2):
    A3 = A1 + A2 # this does not work!
    return A3
  • array_sum(np.array([0, 1, 2]), np.array([2, 3])) returns array [2 4 2]
  • array_sum(np.array([1, 2]), np.array([2, 3])) returns array [3 4]
  • array_sum(np.array([1, 1]), np.array([1, 5, 3])) returns array [2 6 3]

Operators

import numpy as np

A1 = np.array([3, 1, 4, 1])
A2 = np.array([1, 1, 2, 4])
print("+  ", A1 + A2)
print("-  ", A1 - A2)
print("/  ", A1 / A2)
print("*  ", A1 * A2)
print("== ", A1 == A2)
print(">  ", A1 > A2)
print("<  ", A1 < A2)
+   [4 2 6 5]
-   [ 2  0  2 -3]
/   [3.   1.   2.   0.25]
*   [3 1 8 4]
==  [False  True False False]
>   [ True False  True False]
<   [False False False  True]

Arrays and Scalars

import numpy as np

A1 = np.array([4, 2, 8, 1])
print("+  ", A1 + 3)
print("-  ", A1 - 2)
print("/  ", A1 / 2)
print("*  ", A1 * 5)
print("== ", A1 == 2)
print(">  ", A1 > 2)
print("<  ", A1 < 3)
+   [ 7  5 11  4]
-   [ 2  0  6 -1]
/   [2.  1.  4.  0.5]
*   [20 10 40  5]
==  [False  True False False]
>   [ True False  True False]
<   [False  True False  True]

bools are ints

This is a Python thing and is not true everywhere

print(1 + True)
2
  • True is 1
  • False is 0
print(True + True)
2

Why do we care?

Numpy Functions

import numpy as np

np.sum([2, 3, 1, 7, 1])
np.mean([2, 3, 1, 7, 1])
np.median([2, 3, 1, 7, 1])
np.std([2, 3, 1, 7, 1])

data = [1, 2, 8, 3, 4, 1, 0, 4, 5]
standardized_data = (data - np.std(data))/np.mean(data)
print(standardized_data)
[-0.90578946 -0.47673129  2.0976177  -0.04767313  0.38138504 -0.90578946
 -1.33484762  0.38138504  0.8104432 ]

Exercise

Write a function above_mean that takes one argument: a list of numbers (ints or floats):

  • Return how many of the numbers in the list are greater than the mean

Starter code:

  • above_mean([2, 3, 1, 8, 0, -1, 2, 3, 5]) returns int 4
  • above_mean([2, 3, 1, 80, 0, -1, 2, 3, 5]) returns int 1
  • above_mean([2, 3, 1, -80, 0, -1, 2, 3, 5]) returns int 8

Submit as ex3.py.

Linear Algebra (for the brave)

  • numpy is actually a linear algebra library
    • @ operator for matrix multiplication
import numpy as np
A1 = np.array([[1, 2], [3, 4]])
A2 = np.array([[2, 1], [4, 4]])

print("+\n", A1 + A2)
print("@\n", A1 @ A2)
+
 [[3 3]
 [7 8]]
@
 [[10  9]
 [22 19]]

More Linear Algebra

import numpy as np
V1 = np.array([[1, 2, 3, 4]])
V2 = np.array([[2, 1, 4, 4]])

print("+\n", V1 + V2)
print("\n1x4 @ 4x1\n", V1 @ V2.T)
print("\n4x1 @ 1x4\n", V1.T @ V2)
+
 [[3 3 7 8]]

1x4 @ 4x1
 [[32]]

4x1 @ 1x4
 [[ 2  1  4  4]
 [ 4  2  8  8]
 [ 6  3 12 12]
 [ 8  4 16 16]]

Array Shape

import numpy as np

V1 = np.array([[1, 2, 3, 4]])
print("V1: ", V1, "  V1 Shape:", V1.shape)
V2 = np.array([2, 1, 4, 1])
print("V2: ", V2, "  V2 Shape:", V2.shape)

V3 = V1.T
print("V3:\n", V3, "\nV3 Shape:", V3.shape)
V4 = V2.T
print("V4: ", V4, "  V4 Shape:", V4.shape)
V1:  [[1 2 3 4]]   V1 Shape: (1, 4)
V2:  [2 1 4 1]   V2 Shape: (4,)
V3:
 [[1]
 [2]
 [3]
 [4]] 
V3 Shape: (4, 1)
V4:  [2 1 4 1]   V4 Shape: (4,)

Is All Of This Going To Be On The Exam??




No! 😌

Numpy to Know

  • np.array initialization and assignment
  • Array indexing
  • Operators with arrays:
    • + - * / == > < >= <=
  • Operators need same-size arrays

Summary

  • Libraries extend “built-in” Python
    • Libraries provide functions and objects
  • Objects collect data and functionality
  • Objects are (almost always) mutable
    • Passed as references
  • Numpy: numeric processing library

Next week: Exam Review

End of New Material in CSCI 1012.

There’s More Python

5 May “Extra” Lecture:

  • Does not cover any testable material
  • Does not cover any material on homework
  • No lecture exercises

Common Syntax Problems

Syntax 😎

  • Lists are defined with square brackets [ and ]
x = [2, 3, 4]
  • Tuples are defined with parentheses ( and )
y = (3, 4, 5)
  • Dicts are defined with curly braces { and }
z = {"A": 1, 2: 3}

Syntax 😣

  • Lists, Tuples, Dicts, and Strings are all indexed with square brackets
w = "confounded!" # string

x = [2, 3, 4] # list

y = (3, 4, 5) # tuple

z = {"A": 1, 2: 3} # dict

print(w[2], x[0], y[1], z["A"])
n 2 4 1

Syntax 😖

  • Parentheses are used in:
    • Expressions
    • Function definitions
    • Function calls
def f(x, y):
  z = str(x) + ( str(y) * 2 )
  return z

w = f(3, 5)
print(w)
355

Syntax 😩

…parentheses for tuple definitions are often optional

x = 1, 2, 3
print(x)
print(type(x))
(1, 2, 3)
<class 'tuple'>

With parentheses:

x = (1, 2, 3)
print(x)
print(type(x))
(1, 2, 3)
<class 'tuple'>

Syntax 😤

  • Square brackets after a name indicates an index or slice, not a list:
    • x[2] or y["A"]
  • Parentheses after a name indicate a call:
    • f(4, 5) or print("hello", "world")
  • Curly braces are always a dictionary definition:
    • z = {1: 2}
    • Other uses: Python we don’t teach in CSCI 1012

Syntax 😤

  • Function definitions always have the def keyword

  • Parentheses not after a name and with a comma indicate a tuple:

    • (2, 3) or ("yes",)
  • Parentheses not after a name, and with no comma, indicate an expression:

    • (5) or ("otis")