|
35 | 35 | #
|
36 | 36 | #
|
37 | 37 | ## Lets get started!
|
38 |
| -print "Importing numpy" |
| 38 | +print("Importing numpy") |
39 | 39 | import numpy as np
|
40 | 40 |
|
41 | 41 | ## This loads the numpy library and lets us refer to it by the shorthand "np",
|
42 | 42 | ## which is the convention used in the numpy documentation and in many
|
43 | 43 | ## online tutorials/examples
|
44 | 44 |
|
45 |
| -print "Creating arrays" |
| 45 | +print("Creating arrays") |
46 | 46 | ## Now lets make an array to play around with. You can make numpy arrays in
|
47 | 47 | ## a number of ways,
|
48 | 48 | ## Filled with zeros:
|
49 | 49 | zeroArray = np.zeros( (2,3) ) # [[ 0. 0. 0.]
|
50 |
| -print zeroArray # [ 0. 0. 0.]] |
| 50 | +print(zeroArray) # [ 0. 0. 0.]] |
51 | 51 |
|
52 | 52 | ## Or ones:
|
53 | 53 | oneArray = np.ones( (2,3) ) # [[ 1. 1. 1.]
|
54 |
| -print oneArray # [ 1. 1. 1.]] |
| 54 | +print(oneArray) # [ 1. 1. 1.]] |
55 | 55 |
|
56 | 56 | ## Or filled with junk:
|
57 | 57 | emptyArray = np.empty( (2,3) )
|
58 |
| -print emptyArray |
| 58 | +print(emptyArray) |
59 | 59 |
|
60 | 60 | ## Note, emptyArray might look random, but it's just uninitialized which means
|
61 | 61 | ## you shouldn't count on it having any particular data in it, even random
|
62 | 62 | ## data! If you do want random data you can use random():
|
63 | 63 | randomArray = np.random.random( (2,3) )
|
64 |
| -print randomArray |
| 64 | +print(randomArray) |
65 | 65 |
|
66 | 66 | ## If you're following along and trying these commands out, you should have
|
67 | 67 | ## noticed that making randomArray took a lot longer than emptyArray. That's
|
|
74 | 74 | [4,5,6]]
|
75 | 75 |
|
76 | 76 | myArray = np.array(foo) # [[1 2 3]
|
77 |
| -print myArray # [4 5 6]] |
| 77 | +print(myArray) # [4 5 6]] |
78 | 78 |
|
79 | 79 |
|
80 |
| -print "Reshaping arrays" |
| 80 | +print("Reshaping arrays") |
81 | 81 | ## Of course, if you're typing out a range for a larger matrix, it's easier to
|
82 | 82 | ## use arange(...):
|
83 | 83 | rangeArray = np.arange(6,12).reshape( (2,3) ) # [[ 6 7 8]
|
84 |
| -print rangeArray # [ 9 10 11]] |
| 84 | +print(rangeArray) # [ 9 10 11]] |
85 | 85 |
|
86 | 86 | ## there's two things going on here. First, the arange(...) function returns a
|
87 | 87 | ## 1D array similar to what you'd get from using the built-in python function
|
88 | 88 | ## range(...) with the same arguments, except it returns a numpy array
|
89 | 89 | ## instead of a list.
|
90 |
| -print np.arange(6,12) # [ 6 7 8 9 10 11 12] |
| 90 | +print(np.arange(6,12)) # [ 6 7 8 9 10 11 12] |
91 | 91 |
|
92 | 92 | ## the reshape method takes the data in an existing array, and stuffs it into
|
93 | 93 | ## an array with the given shape and returns it.
|
94 |
| -print rangeArray.reshape( (3,2) ) # [[ 6 7] |
| 94 | +print(rangeArray.reshape( (3,2) )) # [[ 6 7] |
95 | 95 | # [ 8 9]
|
96 | 96 | # [10 11]]
|
97 | 97 |
|
98 | 98 | #The original array doesn't change though.
|
99 |
| -print rangeArray # [[ 6 7 8] |
| 99 | +print(rangeArray) # [[ 6 7 8] |
100 | 100 | # [ 9 10 11]
|
101 | 101 |
|
102 | 102 | ## When you use reshape(...) the total number of things in the array must stay
|
|
106 | 106 | squareArray = np.arange(1,10).reshape( (3,3) ) #this is fine, 9 elements
|
107 | 107 |
|
108 | 108 |
|
109 |
| -print "Accessing array elements" |
| 109 | +print("Accessing array elements") |
110 | 110 | ## Accessing an array is also pretty straight forward. You access a specific
|
111 | 111 | ## spot in the table by referring to its row and column inside square braces
|
112 | 112 | ## after the array:
|
113 |
| -print rangeArray[0,1] #7 |
| 113 | +print(rangeArray[0,1]) #7 |
114 | 114 |
|
115 | 115 | ## Note that row and column numbers start from 0, not 1! Numpy also lets you
|
116 | 116 | ## refer to ranges inside an array:
|
117 |
| -print rangeArray[0,0:2] #[6 7] |
118 |
| -print squareArray[0:2,0:2] #[[1 2] # the top left corner of squareArray |
| 117 | +print(rangeArray[0,0:2]) #[6 7] |
| 118 | +print(squareArray[0:2,0:2]) #[[1 2] # the top left corner of squareArray |
119 | 119 | # [4 5]]
|
120 | 120 |
|
121 | 121 | ## These ranges work just like slices and python lists. n:m:t specifies a range
|
122 | 122 | ## that starts at n, and stops before m, in steps of size t. If any of these
|
123 | 123 | ## are left off, they're assumed to be the start, the end+1, and 1 respectively
|
124 |
| -print squareArray[:,0:3:2] #[[1 3] #skip the middle column |
| 124 | +print(squareArray[:,0:3:2]) #[[1 3] #skip the middle column |
125 | 125 | # [4 6]
|
126 | 126 | # [7 9]]
|
127 | 127 |
|
128 | 128 | ## Also like python lists, you can assign values to specific positions, or
|
129 | 129 | ## ranges of values to slices
|
130 |
| -squareArray[0,:] = np.array(range(1,4)) #set the first row to 1,2,3 |
| 130 | +squareArray[0,:] = np.array(list(range(1,4))) #set the first row to 1,2,3 |
131 | 131 | squareArray[1,1] = 0 # set the middle spot to zero
|
132 | 132 | squareArray[2,:] = 1 # set the last row to ones
|
133 |
| -print squareArray # [[1 2 3] |
| 133 | +print(squareArray) # [[1 2 3] |
134 | 134 | # [4 0 6]
|
135 | 135 | # [1 1 1]]
|
136 | 136 |
|
137 | 137 | ## Something new to numpy arrays is indexing using an array of indices:
|
138 | 138 | fibIndices = np.array( [1, 1, 2, 3] )
|
139 | 139 | randomRow = np.random.random( (10,1) ) # an array of 10 random numbers
|
140 |
| -print randomRow |
141 |
| -print randomRow[fibIndices] # the first, first, second and third element of |
| 140 | +print(randomRow) |
| 141 | +print(randomRow[fibIndices]) # the first, first, second and third element of |
142 | 142 | # randomRow
|
143 | 143 |
|
144 | 144 | ## You can also use an array of true/false values to index:
|
145 | 145 | boolIndices = np.array( [[ True, False, True],
|
146 | 146 | [False, True, False],
|
147 | 147 | [ True, False, True]] )
|
148 |
| -print squareArray[boolIndices] # a 1D array with the selected values |
| 148 | +print(squareArray[boolIndices]) # a 1D array with the selected values |
149 | 149 | # [1 3 0 1 1]
|
150 | 150 |
|
151 | 151 | ## It gets a little more complicated with 2D (and higher) arrays. You need
|
152 | 152 | ## two index arrays for a 2D array:
|
153 | 153 | rows = np.array( [[0,0],[2,2]] ) #get the corners of our square array
|
154 | 154 | cols = np.array( [[0,2],[0,2]] )
|
155 |
| -print squareArray[rows,cols] #[[1 3] |
| 155 | +print(squareArray[rows,cols]) #[[1 3] |
156 | 156 | # [1 1]]
|
157 | 157 | boolRows = np.array( [False, True, False] ) # just the middle row
|
158 | 158 | boolCols = np.array( [True, False, True] ) # Not the middle column
|
159 |
| -print squareArray[boolRows,boolCols] # [4 6] |
| 159 | +print(squareArray[boolRows,boolCols]) # [4 6] |
160 | 160 |
|
161 |
| -print "Operations on arrays" |
| 161 | +print("Operations on arrays") |
162 | 162 | ## One useful trick is to create a boolean matrix based on some test and use
|
163 | 163 | ## that as an index in order to get the elements of a matrix that pass the
|
164 | 164 | ## test:
|
165 | 165 | sqAverage = np.average(squareArray) # average(...) returns the average of all
|
166 | 166 | # the elements in the given array
|
167 | 167 | betterThanAverage = squareArray > sqAverage
|
168 |
| -print betterThanAverage #[[False False True] |
| 168 | +print(betterThanAverage) #[[False False True] |
169 | 169 | # [ True False True]
|
170 | 170 | # [False False False]]
|
171 |
| -print squareArray[betterThanAverage] #[3 4 6] |
| 171 | +print(squareArray[betterThanAverage]) #[3 4 6] |
172 | 172 |
|
173 | 173 | ## Indexing like this can also be used to assign values to elements of the
|
174 | 174 | ## array. This is particularly useful if you want to filter an array, say by
|
|
188 | 188 | # truncate them down to integers.
|
189 | 189 | clampedSqArray[ (squareArray-sqAverage) > sqStdDev ] = sqAverage+sqStdDev
|
190 | 190 | clampedSqArray[ (squareArray-sqAverage) < -sqStdDev ] = sqAverage-sqStdDev
|
191 |
| -print clampedSqArray # [[ 1. 2. 3. ] |
| 191 | +print(clampedSqArray) # [[ 1. 2. 3. ] |
192 | 192 | # [ 3.90272394 0.31949828 3.90272394]
|
193 | 193 | # [ 1. 1. 1. ]]
|
194 | 194 |
|
195 | 195 |
|
196 | 196 | ## Multiplying and dividing arrays by numbers does what you'd expect. It
|
197 | 197 | ## multiples/divides element-wise
|
198 |
| -print squareArray * 2 # [[ 2 4 6] |
| 198 | +print(squareArray * 2) # [[ 2 4 6] |
199 | 199 | # [ 8 0 12]
|
200 | 200 | # [ 2 2 2]]
|
201 | 201 |
|
202 | 202 | ## Addition works similarly:
|
203 |
| -print squareArray + np.ones( (3,3) ) #[[2 3 4] |
| 203 | +print(squareArray + np.ones( (3,3) )) #[[2 3 4] |
204 | 204 | # [5 1 7]
|
205 | 205 | # [2 2 2]]
|
206 | 206 |
|
207 | 207 | ## Multiplying two arrays together (of the same size) is also element wise
|
208 |
| -print squareArray * np.arange(1,10).reshape( (3,3) ) #[[ 1 4 9] |
| 208 | +print(squareArray * np.arange(1,10).reshape( (3,3) )) #[[ 1 4 9] |
209 | 209 | # [16 0 36]
|
210 | 210 | # [ 7 8 9]]
|
211 | 211 |
|
212 | 212 | ## Unless you use the dot(...) function, which does matrix multiplication
|
213 | 213 | ## from linear algebra:
|
214 | 214 | matA = np.array( [[1,2],[3,4]] )
|
215 | 215 | matB = np.array( [[5,6],[7,8]] )
|
216 |
| -print np.dot(matA,matB) #[[19 22] |
| 216 | +print(np.dot(matA,matB)) #[[19 22] |
217 | 217 | # [43 50]]
|
218 | 218 |
|
219 | 219 | ## And thats it! There's a lot more to the numpy library, and there are a few
|
|
0 commit comments