In [ ]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import random
Create an 8x10 array of zeros called my_array
. Note that you can do this with any numpy array method (ones
, zeros_like
, ones_like
, etc.). See this page for a full list of routines for array creation.
In [ ]:
a = np.zeros([8,10])
print(a)
You have already created a 1D numpy array of predetermined values by giving np.array
a list. You can make a multi-dimensional numpy array by giving np.array
a set of nested lists (i.e., a list of lists). The following will create a 3x3 array with predetermined values:
In [ ]:
b = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(b)
The array .shape
property tells you how large the array is in each dimension, .ndim
tells you the number of dimensions, and .size
tells you the total number of elements in the array. You can access each of the dimensions dim
by .shape[dim]
.
In [ ]:
print("the shape of this array is:", a.shape)
print("there are:", a.ndim, "dimensions")
print("there are", a.size, "total elements")
for i in range(a.ndim):
print("the size of dimension", i, "is", a.shape[i])
You can manipulate individual cells of an array by:
a[index_1,index_2]
Note that when you print it, the first index corresponds to rows (counting down from the top) and the second index corresponds to columns (counting from the left). Indices in both directions count by zeros.
In [ ]:
a[2,6]=11
#print entire array
print(a)
#print a single element of the array
print(a[2,6])
You can also use the same type of slicing that you use with lists - in other words, python allows you to select some subset of the elements in a list or an array to manipulate or copy. With slicing, there are three values that can be used along each dimension: start
,end
, and step
, separated by colons. Here are some examples in 1D:
myarray[start,end] # items start through end-1
myarray[start:] # items start through the end of the array
myarray[:end] # items from the beginning of the array through end-1
myarray[:] # a copy of the whole array
myarray[start,end,step] # every "step" item from start to end-1
myarray[::step] # every "step" item over the whole array, starting with the first element.
Note that negative indices count from the end of the array, so myarray[-1]
is the last element in the array, myarray[-2]
is the second-to-last element, etc. You can also reverse the order of the array by starting at the end and counting to the beginning by negative numbers -- in other words, myarray[-1::-1]
starts at the end of the array and goes to the first element by counting down by one each time.
In [ ]:
# create a 1D array with values 0...10
c = np.arange(0,10)
# note: the '\n' at the beginning of many of the print statements
# adds a carriage return (blank line)
print("some elements from the middle of the array:",c[3:7] )
print("\nthe second element through the second-to-last element:", c[2:-1])
print("\nthe first half of the array:", c[:5])
print("\nthe second half of the array:", c[5:])
print("\nevery other element from 2-8 (inclusive):",c[2:9:2])
print("\nevery third element in the array:",c[::3])
print("\nreverse the array:",c[-1::-1])
The same sort of technique can be used with a multi-dimensional array, with start
, stop
, and (optionally) step
specified along each dimension, with the dimensions separated by a comma. The syntax would be:
my2Darray[start1:stop1:step1, start2:stop2:step2]
With the same rules as above. You can also combine slicing with fixed indices to get some or all elements from a single row or column of your array.
For example, array b
created above is a 3x3 array with the values 1-9 stored in it. We can do several different things:
b[0,:] # get the first row
b[:,2] # get the third column
b[1,::2] # get every other element of the first row, starting at element 0
b[:2,:2] # get a square array containing the first two elements along each dimension
b[-2:,-2:] # get a square array containing the last two elements along each dimension
b[::2,::2] # get a square array of every other element along each dimension
b[-1::-1,-1::-1] # original sized array, but reversed along both dimensions
In [ ]:
print("the array b:\n",b,"\n")
# To get a square array containing the first two elements along each dimension:
print("the first row:", b[0,:])
print("\nthe third column:",b[:,2])
print("\nevery other element of the second row, starting with element 0:",b[1,::2])
print("\nsquare array of first two elements along each dimension:\n",b[:2,:2])
print("\nsquare array of last two elements along each dimension:\n",b[-2:,-2:])
print("\nsquare array of every other element along each dimension:\n",b[::2,::2])
print("\nreversed array:\n",b[-1::-1,-1::-1])
In [ ]:
c = np.full((4,4),10.0) # makes an array of shape (4,4) where all elements are value 10.0
d = c
print("c:\n",c, "\nd:\n", d)
The two arrays are the same, which is what you would expect. But, what happens if we make changes to array d?
In [ ]:
d[:,0] = -1.0 # make column 0 equal to -1
d[:,2] = -6.0 # make column 2 equal to -6
print("c:\n",c, "\nd:\n", d)
Arrays c
and d
are identical, even though you only changed d
!
So what's going on here? When you equate arrays in Numpy (i.e., d = c
), you create a reference, rather than copying the array -- in other words, the array d
is not a distinct array, but rather points to the array c
in memory. Any modification to either c
or d
will be seen by both. To actually make a copy, you have to use the np.copy()
method:
In [ ]:
e = np.full((4,4),10.0) # makes an array of shape (4,4) where all elements are value 10.0
f = np.copy(e)
f[:,0] = -1.0 # make column 0 equal to -1
f[:,2] = -6.0 # make column 2 equal to -6
print("e:\n",e, "\nf:\n", f)
You can also make a copy of a subset of an arrays:
In [ ]:
g = np.full((4,4),10.0) # makes an array of shape (4,4) where all elements are value 10.0
h = np.copy(g[0:2,0:2])
print("g:\n",g, "\nh:\n", h)
Note that you can also create an array that references a subset of another array rather than copies it, and manipulate that in any way you want. The changes will then appear in both the new array and your original array. For example:
In [ ]:
i = np.full((4,4),10.0) # makes an array of shape (4,4) where all elements are value 10.0
j = i[0:2,0:2]
print("\nunmodified arrays:\n")
print("i:\n",i, "\nj:\n", j)
print("\narrays after modification:\n")
j[1,1]=-999.0
print("i:\n",i, "\nj:\n", j)
Numpy has a random
module that can be used to generate random numbers in a similar way to the standard Python random
module, but with the added advantage that it can do so for arrays of values. Two commonly-used methods are:
In [ ]:
random_float_array = np.random.random((5,5))
print(random_float_array)
random_int_array = np.random.randint(0,10,(5,5))
print("\n",random_int_array)
It's easy to plot 2D Numpy arrays in matplotlib using the pyplot matshow
method:
In [ ]:
new_rand_array = np.random.random((100,100))
plt.matshow(new_rand_array)
# uncomment the following line to save the figure to your hard drive!
#plt.savefig("myimage.png")
And you can turn off the array axes with the following incantation:
In [ ]:
myplot = plt.matshow(new_rand_array)
myplot.axes.get_xaxis().set_visible(False)
myplot.axes.get_yaxis().set_visible(False)
In [ ]:
# interpolation='none' keeps imshow() from trying to interpolate between values and
# making it look fuzzy.
# cmap='mapname' changes the color map.
# vmin, vmax sets the range of the color bar (from 0.0 - 0.5 in this example)
myplot = plt.imshow(new_rand_array, interpolation='none',cmap='hot',vmin=0.0,vmax=0.5)
# uncomment the following lines to remove the axis labels
#myplot.axes.get_xaxis().set_visible(False)
#myplot.axes.get_yaxis().set_visible(False)
# uncomment the following line to save the figure to your hard drive!
#plt.savefig("myimage.png")