Basic objects in Python¶

The Python list¶

In [1]:
x = [1,2,3,8]
type(x)
Out[1]:
list
In [2]:
y = ["a","b","z"]
type(y)
Out[2]:
list
In [3]:
z = [True, False, False]
print(z)
[True, False, False]

A list doesn't have to have all one type of value...

In [4]:
w = ["Karl", 40, True] # write comments after # in Python
print(w)
['Karl', 40, True]

Accessing entries of a list...

In [5]:
print(w[0]) # indexing begins at zero.
print(w[1]) # second value
Karl
40
In [6]:
u = list(range(0,12,2)) # includes 0 but not 12
print(u)
[0, 2, 4, 6, 8, 10]

The print function works kind of like the paste function in R

In [7]:
print("The first entry of w is ",w[0])
The first entry of w is  Karl

Can easily concatenate character strings in Python:

In [8]:
"The second entry of y is " + y[1] 
Out[8]:
'The second entry of y is b'
In [9]:
"The second entry of x is " + str(x[1]) + "."
Out[9]:
'The second entry of x is 2.'
In [10]:
print("The first entry of x is ",x[0])
The first entry of x is  1

creating several objects at once:

In [11]:
u, v, r = [50,60], "Hello", [True, False,False]
print(u)
print(v)
print(r)
[50, 60]
Hello
[True, False, False]

Lists are NOT like vectors in R:

In [12]:
print(u*4) # just repeats the list 4 times
print(v*8)
[50, 60, 50, 60, 50, 60, 50, 60]
HelloHelloHelloHelloHelloHelloHelloHello

We can edit the values in a list:

In [13]:
u[0] = 100
print(u)
[100, 60]

The Python Tuple¶

In [14]:
greetings = ('hi','hello',"what's up")
print(greetings)
type(greetings)
('hi', 'hello', "what's up")
Out[14]:
tuple
In [15]:
x = ("b",1) # can have different types of values.
type(x)
Out[15]:
tuple
In [16]:
# greetings[2] = "howdy" # this won't work because you cannot edit a tuple.
In [17]:
greetings_list = list(greetings)
type(greetings_list)
print(greetings_list)
['hi', 'hello', "what's up"]

The Python Dictionary¶

In [18]:
# a set of key-value pairs

stat540 = {'classroom' : 'LC 103', 'nstudents' : 29, 'days' : ["Tuesday", "Thursday"]}
type(stat540)
print(stat540['classroom'])
print(stat540['days'])
print(stat540['nstudents'])
LC 103
['Tuesday', 'Thursday']
29
In [19]:
stat540['days'][1] = 'Friday'
print(stat540['days'])
['Tuesday', 'Friday']

NumPy Arrays¶

NumPy arrays are like vectors, matrices, and arrays in R.

In [20]:
import numpy as np
In [21]:
x = np.array([1,5,2,8,9,0,-1,3]) # this is like a numeric vector
type(x)
print(x)
print(x*2)
[ 1  5  2  8  9  0 -1  3]
[ 2 10  4 16 18  0 -2  6]
In [22]:
a = -1
b = 1
seq = np.arange(a,b,1/4)  # kind of like the seq() function in R
print(seq)
[-1.   -0.75 -0.5  -0.25  0.    0.25  0.5   0.75]

Get the size/dimension of a numpy array:

In [23]:
np.shape(seq)
Out[23]:
(8,)
In [24]:
np.size(seq)
Out[24]:
8
In [25]:
np.ndim(seq)
Out[25]:
1
In [26]:
li = [[2,3,4],[4,5,6]]
print(li)
type(li)
[[2, 3, 4], [4, 5, 6]]
Out[26]:
list
In [27]:
M = np.array(li)
print(M)
print(np.ndim(M))
print(np.shape(M))
print(np.size(M))
[[2 3 4]
 [4 5 6]]
2
(2, 3)
6

NumPy arrays must have values all of one type:

In [28]:
A = np.array([[1,2,3],['a','b','c']])
print(A)
[['1' '2' '3']
 ['a' 'b' 'c']]
In [29]:
A = np.array([[False,False,True],['a','b','c']]) # coercion to character strings
print(A)
[['False' 'False' 'True']
 ['a' 'b' 'c']]

More useful functions:

In [30]:
Z = np.zeros((4,2))
print(Z)
[[0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]]
In [31]:
Z = np.ones((3,4))
print(Z)
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]
In [32]:
Z = np.full((5,6),29)
print(Z)
[[29 29 29 29 29 29]
 [29 29 29 29 29 29]
 [29 29 29 29 29 29]
 [29 29 29 29 29 29]
 [29 29 29 29 29 29]]

SUPER useful:

In [33]:
x = np.linspace(0,1,21) #  This one is also like the seq() function in R
print(x)
[0.   0.05 0.1  0.15 0.2  0.25 0.3  0.35 0.4  0.45 0.5  0.55 0.6  0.65
 0.7  0.75 0.8  0.85 0.9  0.95 1.  ]
In [34]:
?np.linspace
Signature:      
np.linspace(
    start,
    stop,
    num=50,
    endpoint=True,
    retstep=False,
    dtype=None,
    axis=0,
)
Call signature:  np.linspace(*args, **kwargs)
Type:            _ArrayFunctionDispatcher
String form:     <function linspace at 0x105f6bd80>
File:            /opt/anaconda3/lib/python3.12/site-packages/numpy/core/function_base.py
Docstring:      
Return evenly spaced numbers over a specified interval.

Returns `num` evenly spaced samples, calculated over the
interval [`start`, `stop`].

The endpoint of the interval can optionally be excluded.

.. versionchanged:: 1.16.0
    Non-scalar `start` and `stop` are now supported.

.. versionchanged:: 1.20.0
    Values are rounded towards ``-inf`` instead of ``0`` when an
    integer ``dtype`` is specified. The old behavior can
    still be obtained with ``np.linspace(start, stop, num).astype(int)``

Parameters
----------
start : array_like
    The starting value of the sequence.
stop : array_like
    The end value of the sequence, unless `endpoint` is set to False.
    In that case, the sequence consists of all but the last of ``num + 1``
    evenly spaced samples, so that `stop` is excluded.  Note that the step
    size changes when `endpoint` is False.
num : int, optional
    Number of samples to generate. Default is 50. Must be non-negative.
endpoint : bool, optional
    If True, `stop` is the last sample. Otherwise, it is not included.
    Default is True.
retstep : bool, optional
    If True, return (`samples`, `step`), where `step` is the spacing
    between samples.
dtype : dtype, optional
    The type of the output array.  If `dtype` is not given, the data type
    is inferred from `start` and `stop`. The inferred dtype will never be
    an integer; `float` is chosen even if the arguments would produce an
    array of integers.

    .. versionadded:: 1.9.0

axis : int, optional
    The axis in the result to store the samples.  Relevant only if start
    or stop are array-like.  By default (0), the samples will be along a
    new axis inserted at the beginning. Use -1 to get an axis at the end.

    .. versionadded:: 1.16.0

Returns
-------
samples : ndarray
    There are `num` equally spaced samples in the closed interval
    ``[start, stop]`` or the half-open interval ``[start, stop)``
    (depending on whether `endpoint` is True or False).
step : float, optional
    Only returned if `retstep` is True

    Size of spacing between samples.


See Also
--------
arange : Similar to `linspace`, but uses a step size (instead of the
         number of samples).
geomspace : Similar to `linspace`, but with numbers spaced evenly on a log
            scale (a geometric progression).
logspace : Similar to `geomspace`, but with the end points specified as
           logarithms.
:ref:`how-to-partition`

Examples
--------
>>> np.linspace(2.0, 3.0, num=5)
array([2.  , 2.25, 2.5 , 2.75, 3.  ])
>>> np.linspace(2.0, 3.0, num=5, endpoint=False)
array([2. ,  2.2,  2.4,  2.6,  2.8])
>>> np.linspace(2.0, 3.0, num=5, retstep=True)
(array([2.  ,  2.25,  2.5 ,  2.75,  3.  ]), 0.25)

Graphical illustration:

>>> import matplotlib.pyplot as plt
>>> N = 8
>>> y = np.zeros(N)
>>> x1 = np.linspace(0, 10, N, endpoint=True)
>>> x2 = np.linspace(0, 10, N, endpoint=False)
>>> plt.plot(x1, y, 'o')
[<matplotlib.lines.Line2D object at 0x...>]
>>> plt.plot(x2, y + 0.5, 'o')
[<matplotlib.lines.Line2D object at 0x...>]
>>> plt.ylim([-0.5, 1])
(-0.5, 1)
>>> plt.show()
Class docstring:
Class to wrap functions with checks for __array_function__ overrides.

All arguments are required, and can only be passed by position.

Parameters
----------
dispatcher : function or None
    The dispatcher function that returns a single sequence-like object
    of all arguments relevant.  It must have the same signature (except
    the default values) as the actual implementation.
    If ``None``, this is a ``like=`` dispatcher and the
    ``_ArrayFunctionDispatcher`` must be called with ``like`` as the
    first (additional and positional) argument.
implementation : function
    Function that implements the operation on NumPy arrays without
    overrides.  Arguments passed calling the ``_ArrayFunctionDispatcher``
    will be forwarded to this (and the ``dispatcher``) as if using
    ``*args, **kwargs``.

Attributes
----------
_implementation : function
    The original implementation passed in.
In [35]:
np.diag(np.ones(5))
Out[35]:
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])

Outer function is similar to the outer function in R

In [36]:
x = np.arange(1,4)
y = np.arange(1,6)
print(x)
print(y)
print(np.outer(x,y)) # gives a matrix with products of all combinations of x and y entries
[1 2 3]
[1 2 3 4 5]
[[ 1  2  3  4  5]
 [ 2  4  6  8 10]
 [ 3  6  9 12 15]]

Accessing entries of a NumPy array¶

In [37]:
print(seq)
print(seq[0]) # use square brackets
print(seq[3:7]) # a range of entries
print(seq[3:]) # take entries beginning at index 3 and beyond
print(seq[:3]) # up to but not including 3
print(seq[::3]) # every 3rd entry, beginning at index 0
print(seq[-1]) # negative indices go from the end backwards
[-1.   -0.75 -0.5  -0.25  0.    0.25  0.5   0.75]
-1.0
[-0.25  0.    0.25  0.5 ]
[-0.25  0.    0.25  0.5   0.75]
[-1.   -0.75 -0.5 ]
[-1.   -0.25  0.5 ]
0.75
In [38]:
print(M)
print(M[0,0])
print(M[0,:]) # take first row
print(M[:,0]) # take first column
print(M[-1,1]) # can use negative indexing to come from "the end"
print(M[1,1]) #
M[0,2] = 99
print(M)
[[2 3 4]
 [4 5 6]]
2
[2 3 4]
[2 4]
5
5
[[ 2  3 99]
 [ 4  5  6]]

Accessing "methods" for Python objects¶

In [39]:
print(M)
print(np.transpose(M))
print(M.transpose()) # another way to apply the np.transpose function
[[ 2  3 99]
 [ 4  5  6]]
[[ 2  4]
 [ 3  5]
 [99  6]]
[[ 2  4]
 [ 3  5]
 [99  6]]
In [40]:
print(M)
print(np.sum(M))
print(M.sum())
print(M.sum(axis = 1))
print(M.sum(axis = 0))
[[ 2  3 99]
 [ 4  5  6]]
119
119
[104  15]
[  6   8 105]