|
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