├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── 100_Numpy_exercises.ipynb ├── 100_Numpy_exercises.md ├── 100_Numpy_exercises_with_hints.md ├── 100_Numpy_exercises_with_hints_with_solutions.md ├── 100_Numpy_exercises_with_solutions.md ├── 100_Numpy_random.ipynb ├── LICENSE.txt ├── README.md ├── generators.py ├── initialise.py ├── requirements.txt ├── runtime.txt └── source ├── exercises100.ktx └── headers.ktx /.gitattributes: -------------------------------------------------------------------------------- 1 | *.md linguist-language=Python 2 | *.ipynb linguist-language=Python 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: rougier # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints/ 2 | __pycache__ 3 | venv 4 | .idea 5 | .vscode 6 | Untitled.ipynb 7 | -------------------------------------------------------------------------------- /100_Numpy_exercises.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # 100 numpy exercises 5 | 6 | This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow 7 | and in the numpy documentation. The goal of this collection is to offer a quick reference for both old 8 | and new users but also to provide a set of exercises for those who teach. 9 | 10 | 11 | If you find an error or think you've a better way to solve some of them, feel 12 | free to open an issue at . 13 | File automatically generated. See the documentation to update questions/answers/hints programmatically. 14 | 15 | #### 1. Import the numpy package under the name `np` (★☆☆) 16 | 17 | #### 2. Print the numpy version and the configuration (★☆☆) 18 | 19 | #### 3. Create a null vector of size 10 (★☆☆) 20 | 21 | #### 4. How to find the memory size of any array (★☆☆) 22 | 23 | #### 5. How to get the documentation of the numpy add function from the command line? (★☆☆) 24 | 25 | #### 6. Create a null vector of size 10 but the fifth value which is 1 (★☆☆) 26 | 27 | #### 7. Create a vector with values ranging from 10 to 49 (★☆☆) 28 | 29 | #### 8. Reverse a vector (first element becomes last) (★☆☆) 30 | 31 | #### 9. Create a 3x3 matrix with values ranging from 0 to 8 (★☆☆) 32 | 33 | #### 10. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆) 34 | 35 | #### 11. Create a 3x3 identity matrix (★☆☆) 36 | 37 | #### 12. Create a 3x3x3 array with random values (★☆☆) 38 | 39 | #### 13. Create a 10x10 array with random values and find the minimum and maximum values (★☆☆) 40 | 41 | #### 14. Create a random vector of size 30 and find the mean value (★☆☆) 42 | 43 | #### 15. Create a 2d array with 1 on the border and 0 inside (★☆☆) 44 | 45 | #### 16. How to add a border (filled with 0's) around an existing array? (★☆☆) 46 | 47 | #### 17. What is the result of the following expression? (★☆☆) 48 | ```python 49 | 0 * np.nan 50 | np.nan == np.nan 51 | np.inf > np.nan 52 | np.nan - np.nan 53 | np.nan in set([np.nan]) 54 | 0.3 == 3 * 0.1 55 | ``` 56 | 57 | #### 18. Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆) 58 | 59 | #### 19. Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆) 60 | 61 | #### 20. Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element? (★☆☆) 62 | 63 | #### 21. Create a checkerboard 8x8 matrix using the tile function (★☆☆) 64 | 65 | #### 22. Normalize a 5x5 random matrix (★☆☆) 66 | 67 | #### 23. Create a custom dtype that describes a color as four unsigned bytes (RGBA) (★☆☆) 68 | 69 | #### 24. Multiply a 5x3 matrix by a 3x2 matrix (real matrix product) (★☆☆) 70 | 71 | #### 25. Given a 1D array, negate all elements which are between 3 and 8, in place. (★☆☆) 72 | 73 | #### 26. What is the output of the following script? (★☆☆) 74 | ```python 75 | # Author: Jake VanderPlas 76 | 77 | print(sum(range(5),-1)) 78 | from numpy import * 79 | print(sum(range(5),-1)) 80 | ``` 81 | 82 | #### 27. Consider an integer vector Z, which of these expressions are legal? (★☆☆) 83 | ```python 84 | Z**Z 85 | 2 << Z >> 2 86 | Z <- Z 87 | 1j*Z 88 | Z/1/1 89 | ZZ 90 | ``` 91 | 92 | #### 28. What are the result of the following expressions? (★☆☆) 93 | ```python 94 | np.array(0) / np.array(0) 95 | np.array(0) // np.array(0) 96 | np.array([np.nan]).astype(int).astype(float) 97 | ``` 98 | 99 | #### 29. How to round away from zero a float array ? (★☆☆) 100 | 101 | #### 30. How to find common values between two arrays? (★☆☆) 102 | 103 | #### 31. How to ignore all numpy warnings (not recommended)? (★☆☆) 104 | 105 | #### 32. Is the following expressions true? (★☆☆) 106 | ```python 107 | np.sqrt(-1) == np.emath.sqrt(-1) 108 | ``` 109 | 110 | #### 33. How to get the dates of yesterday, today and tomorrow? (★☆☆) 111 | 112 | #### 34. How to get all the dates corresponding to the month of July 2016? (★★☆) 113 | 114 | #### 35. How to compute ((A+B)*(-A/2)) in place (without copy)? (★★☆) 115 | 116 | #### 36. Extract the integer part of a random array of positive numbers using 4 different methods (★★☆) 117 | 118 | #### 37. Create a 5x5 matrix with row values ranging from 0 to 4 (★★☆) 119 | 120 | #### 38. Consider a generator function that generates 10 integers and use it to build an array (★☆☆) 121 | 122 | #### 39. Create a vector of size 10 with values ranging from 0 to 1, both excluded (★★☆) 123 | 124 | #### 40. Create a random vector of size 10 and sort it (★★☆) 125 | 126 | #### 41. How to sum a small array faster than np.sum? (★★☆) 127 | 128 | #### 42. Consider two random array A and B, check if they are equal (★★☆) 129 | 130 | #### 43. Make an array immutable (read-only) (★★☆) 131 | 132 | #### 44. Consider a random 10x2 matrix representing cartesian coordinates, convert them to polar coordinates (★★☆) 133 | 134 | #### 45. Create random vector of size 10 and replace the maximum value by 0 (★★☆) 135 | 136 | #### 46. Create a structured array with `x` and `y` coordinates covering the [0,1]x[0,1] area (★★☆) 137 | 138 | #### 47. Given two arrays, X and Y, construct the Cauchy matrix C (Cij =1/(xi - yj)) (★★☆) 139 | 140 | #### 48. Print the minimum and maximum representable value for each numpy scalar type (★★☆) 141 | 142 | #### 49. How to print all the values of an array? (★★☆) 143 | 144 | #### 50. How to find the closest value (to a given scalar) in a vector? (★★☆) 145 | 146 | #### 51. Create a structured array representing a position (x,y) and a color (r,g,b) (★★☆) 147 | 148 | #### 52. Consider a random vector with shape (100,2) representing coordinates, find point by point distances (★★☆) 149 | 150 | #### 53. How to convert a float (32 bits) array into an integer (32 bits) in place? 151 | 152 | #### 54. How to read the following file? (★★☆) 153 | ``` 154 | 1, 2, 3, 4, 5 155 | 6, , , 7, 8 156 | , , 9,10,11 157 | ``` 158 | 159 | #### 55. What is the equivalent of enumerate for numpy arrays? (★★☆) 160 | 161 | #### 56. Generate a generic 2D Gaussian-like array (★★☆) 162 | 163 | #### 57. How to randomly place p elements in a 2D array? (★★☆) 164 | 165 | #### 58. Subtract the mean of each row of a matrix (★★☆) 166 | 167 | #### 59. How to sort an array by the nth column? (★★☆) 168 | 169 | #### 60. How to tell if a given 2D array has null columns? (★★☆) 170 | 171 | #### 61. Find the nearest value from a given value in an array (★★☆) 172 | 173 | #### 62. Considering two arrays with shape (1,3) and (3,1), how to compute their sum using an iterator? (★★☆) 174 | 175 | #### 63. Create an array class that has a name attribute (★★☆) 176 | 177 | #### 64. Consider a given vector, how to add 1 to each element indexed by a second vector (be careful with repeated indices)? (★★★) 178 | 179 | #### 65. How to accumulate elements of a vector (X) to an array (F) based on an index list (I)? (★★★) 180 | 181 | #### 66. Considering a (w,h,3) image of (dtype=ubyte), compute the number of unique colors (★★☆) 182 | 183 | #### 67. Considering a four dimensions array, how to get sum over the last two axis at once? (★★★) 184 | 185 | #### 68. Considering a one-dimensional vector D, how to compute means of subsets of D using a vector S of same size describing subset indices? (★★★) 186 | 187 | #### 69. How to get the diagonal of a dot product? (★★★) 188 | 189 | #### 70. Consider the vector [1, 2, 3, 4, 5], how to build a new vector with 3 consecutive zeros interleaved between each value? (★★★) 190 | 191 | #### 71. Consider an array of dimension (5,5,3), how to mulitply it by an array with dimensions (5,5)? (★★★) 192 | 193 | #### 72. How to swap two rows of an array? (★★★) 194 | 195 | #### 73. Consider a set of 10 triplets describing 10 triangles (with shared vertices), find the set of unique line segments composing all the triangles (★★★) 196 | 197 | #### 74. Given a sorted array C that corresponds to a bincount, how to produce an array A such that np.bincount(A) == C? (★★★) 198 | 199 | #### 75. How to compute averages using a sliding window over an array? (★★★) 200 | 201 | #### 76. Consider a one-dimensional array Z, build a two-dimensional array whose first row is (Z[0],Z[1],Z[2]) and each subsequent row is shifted by 1 (last row should be (Z[-3],Z[-2],Z[-1]) (★★★) 202 | 203 | #### 77. How to negate a boolean, or to change the sign of a float inplace? (★★★) 204 | 205 | #### 78. Consider 2 sets of points P0,P1 describing lines (2d) and a point p, how to compute distance from p to each line i (P0[i],P1[i])? (★★★) 206 | 207 | #### 79. Consider 2 sets of points P0,P1 describing lines (2d) and a set of points P, how to compute distance from each point j (P[j]) to each line i (P0[i],P1[i])? (★★★) 208 | 209 | #### 80. Consider an arbitrary array, write a function that extract a subpart with a fixed shape and centered on a given element (pad with a `fill` value when necessary) (★★★) 210 | 211 | #### 81. Consider an array Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], how to generate an array R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]]? (★★★) 212 | 213 | #### 82. Compute a matrix rank (★★★) 214 | 215 | #### 83. How to find the most frequent value in an array? 216 | 217 | #### 84. Extract all the contiguous 3x3 blocks from a random 10x10 matrix (★★★) 218 | 219 | #### 85. Create a 2D array subclass such that Z[i,j] == Z[j,i] (★★★) 220 | 221 | #### 86. Consider a set of p matrices with shape (n,n) and a set of p vectors with shape (n,1). How to compute the sum of of the p matrix products at once? (result has shape (n,1)) (★★★) 222 | 223 | #### 87. Consider a 16x16 array, how to get the block-sum (block size is 4x4)? (★★★) 224 | 225 | #### 88. How to implement the Game of Life using numpy arrays? (★★★) 226 | 227 | #### 89. How to get the n largest values of an array (★★★) 228 | 229 | #### 90. Given an arbitrary number of vectors, build the cartesian product (every combinations of every item) (★★★) 230 | 231 | #### 91. How to create a record array from a regular array? (★★★) 232 | 233 | #### 92. Consider a large vector Z, compute Z to the power of 3 using 3 different methods (★★★) 234 | 235 | #### 93. Consider two arrays A and B of shape (8,3) and (2,2). How to find rows of A that contain elements of each row of B regardless of the order of the elements in B? (★★★) 236 | 237 | #### 94. Considering a 10x3 matrix, extract rows with unequal values (e.g. [2,2,3]) (★★★) 238 | 239 | #### 95. Convert a vector of ints into a matrix binary representation (★★★) 240 | 241 | #### 96. Given a two dimensional array, how to extract unique rows? (★★★) 242 | 243 | #### 97. Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function (★★★) 244 | 245 | #### 98. Considering a path described by two vectors (X,Y), how to sample it using equidistant samples (★★★)? 246 | 247 | #### 99. Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n. (★★★) 248 | 249 | #### 100. Compute bootstrapped 95% confidence intervals for the mean of a 1D array X (i.e., resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means). (★★★) 250 | -------------------------------------------------------------------------------- /100_Numpy_exercises_with_hints.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # 100 numpy exercises 5 | 6 | This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow 7 | and in the numpy documentation. The goal of this collection is to offer a quick reference for both old 8 | and new users but also to provide a set of exercises for those who teach. 9 | 10 | 11 | If you find an error or think you've a better way to solve some of them, feel 12 | free to open an issue at . 13 | File automatically generated. See the documentation to update questions/answers/hints programmatically. 14 | 15 | #### 1. Import the numpy package under the name `np` (★☆☆) 16 | `hint: import … as` 17 | #### 2. Print the numpy version and the configuration (★☆☆) 18 | `hint: np.__version__, np.show_config)` 19 | #### 3. Create a null vector of size 10 (★☆☆) 20 | `hint: np.zeros` 21 | #### 4. How to find the memory size of any array (★☆☆) 22 | `hint: size, itemsize` 23 | #### 5. How to get the documentation of the numpy add function from the command line? (★☆☆) 24 | `hint: np.info` 25 | #### 6. Create a null vector of size 10 but the fifth value which is 1 (★☆☆) 26 | `hint: array[4]` 27 | #### 7. Create a vector with values ranging from 10 to 49 (★☆☆) 28 | `hint: arange` 29 | #### 8. Reverse a vector (first element becomes last) (★☆☆) 30 | `hint: array[::-1]` 31 | #### 9. Create a 3x3 matrix with values ranging from 0 to 8 (★☆☆) 32 | `hint: reshape` 33 | #### 10. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆) 34 | `hint: np.nonzero` 35 | #### 11. Create a 3x3 identity matrix (★☆☆) 36 | `hint: np.eye` 37 | #### 12. Create a 3x3x3 array with random values (★☆☆) 38 | `hint: np.random.random` 39 | #### 13. Create a 10x10 array with random values and find the minimum and maximum values (★☆☆) 40 | `hint: min, max` 41 | #### 14. Create a random vector of size 30 and find the mean value (★☆☆) 42 | `hint: mean` 43 | #### 15. Create a 2d array with 1 on the border and 0 inside (★☆☆) 44 | `hint: array[1:-1, 1:-1]` 45 | #### 16. How to add a border (filled with 0's) around an existing array? (★☆☆) 46 | `hint: np.pad` 47 | #### 17. What is the result of the following expression? (★☆☆) 48 | ```python 49 | 0 * np.nan 50 | np.nan == np.nan 51 | np.inf > np.nan 52 | np.nan - np.nan 53 | np.nan in set([np.nan]) 54 | 0.3 == 3 * 0.1 55 | ``` 56 | `hint: NaN = not a number, inf = infinity` 57 | #### 18. Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆) 58 | `hint: np.diag` 59 | #### 19. Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆) 60 | `hint: array[::2]` 61 | #### 20. Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element? (★☆☆) 62 | `hint: np.unravel_index` 63 | #### 21. Create a checkerboard 8x8 matrix using the tile function (★☆☆) 64 | `hint: np.tile` 65 | #### 22. Normalize a 5x5 random matrix (★☆☆) 66 | `hint: (x -mean)/std` 67 | #### 23. Create a custom dtype that describes a color as four unsigned bytes (RGBA) (★☆☆) 68 | `hint: np.dtype` 69 | #### 24. Multiply a 5x3 matrix by a 3x2 matrix (real matrix product) (★☆☆) 70 | `hint:` 71 | #### 25. Given a 1D array, negate all elements which are between 3 and 8, in place. (★☆☆) 72 | `hint: >, <` 73 | #### 26. What is the output of the following script? (★☆☆) 74 | ```python 75 | # Author: Jake VanderPlas 76 | 77 | print(sum(range(5),-1)) 78 | from numpy import * 79 | print(sum(range(5),-1)) 80 | ``` 81 | `hint: np.sum` 82 | #### 27. Consider an integer vector Z, which of these expressions are legal? (★☆☆) 83 | ```python 84 | Z**Z 85 | 2 << Z >> 2 86 | Z <- Z 87 | 1j*Z 88 | Z/1/1 89 | ZZ 90 | ``` 91 | `No hints provided...` 92 | #### 28. What are the result of the following expressions? (★☆☆) 93 | ```python 94 | np.array(0) / np.array(0) 95 | np.array(0) // np.array(0) 96 | np.array([np.nan]).astype(int).astype(float) 97 | ``` 98 | `No hints provided...` 99 | #### 29. How to round away from zero a float array ? (★☆☆) 100 | `hint: np.uniform, np.copysign, np.ceil, np.abs, np.where` 101 | #### 30. How to find common values between two arrays? (★☆☆) 102 | `hint: np.intersect1d` 103 | #### 31. How to ignore all numpy warnings (not recommended)? (★☆☆) 104 | `hint: np.seterr, np.errstate` 105 | #### 32. Is the following expressions true? (★☆☆) 106 | ```python 107 | np.sqrt(-1) == np.emath.sqrt(-1) 108 | ``` 109 | `hint: imaginary number` 110 | #### 33. How to get the dates of yesterday, today and tomorrow? (★☆☆) 111 | `hint: np.datetime64, np.timedelta64` 112 | #### 34. How to get all the dates corresponding to the month of July 2016? (★★☆) 113 | `hint: np.arange(dtype=datetime64['D'])` 114 | #### 35. How to compute ((A+B)*(-A/2)) in place (without copy)? (★★☆) 115 | `hint: np.add(out=), np.negative(out=), np.multiply(out=), np.divide(out=)` 116 | #### 36. Extract the integer part of a random array of positive numbers using 4 different methods (★★☆) 117 | `hint: %, np.floor, astype, np.trunc` 118 | #### 37. Create a 5x5 matrix with row values ranging from 0 to 4 (★★☆) 119 | `hint: np.arange` 120 | #### 38. Consider a generator function that generates 10 integers and use it to build an array (★☆☆) 121 | `hint: np.fromiter` 122 | #### 39. Create a vector of size 10 with values ranging from 0 to 1, both excluded (★★☆) 123 | `hint: np.linspace` 124 | #### 40. Create a random vector of size 10 and sort it (★★☆) 125 | `hint: sort` 126 | #### 41. How to sum a small array faster than np.sum? (★★☆) 127 | `hint: np.add.reduce` 128 | #### 42. Consider two random array A and B, check if they are equal (★★☆) 129 | `hint: np.allclose, np.array_equal` 130 | #### 43. Make an array immutable (read-only) (★★☆) 131 | `hint: flags.writeable` 132 | #### 44. Consider a random 10x2 matrix representing cartesian coordinates, convert them to polar coordinates (★★☆) 133 | `hint: np.sqrt, np.arctan2` 134 | #### 45. Create random vector of size 10 and replace the maximum value by 0 (★★☆) 135 | `hint: argmax` 136 | #### 46. Create a structured array with `x` and `y` coordinates covering the [0,1]x[0,1] area (★★☆) 137 | `hint: np.meshgrid` 138 | #### 47. Given two arrays, X and Y, construct the Cauchy matrix C (Cij =1/(xi - yj)) (★★☆) 139 | `hint: np.subtract.outer` 140 | #### 48. Print the minimum and maximum representable value for each numpy scalar type (★★☆) 141 | `hint: np.iinfo, np.finfo, eps` 142 | #### 49. How to print all the values of an array? (★★☆) 143 | `hint: np.set_printoptions` 144 | #### 50. How to find the closest value (to a given scalar) in a vector? (★★☆) 145 | `hint: argmin` 146 | #### 51. Create a structured array representing a position (x,y) and a color (r,g,b) (★★☆) 147 | `hint: dtype` 148 | #### 52. Consider a random vector with shape (100,2) representing coordinates, find point by point distances (★★☆) 149 | `hint: np.atleast_2d, T, np.sqrt` 150 | #### 53. How to convert a float (32 bits) array into an integer (32 bits) in place? 151 | `hint: view and [:] =` 152 | #### 54. How to read the following file? (★★☆) 153 | ``` 154 | 1, 2, 3, 4, 5 155 | 6, , , 7, 8 156 | , , 9,10,11 157 | ``` 158 | `hint: np.genfromtxt` 159 | #### 55. What is the equivalent of enumerate for numpy arrays? (★★☆) 160 | `hint: np.ndenumerate, np.ndindex` 161 | #### 56. Generate a generic 2D Gaussian-like array (★★☆) 162 | `hint: np.meshgrid, np.exp` 163 | #### 57. How to randomly place p elements in a 2D array? (★★☆) 164 | `hint: np.put, np.random.choice` 165 | #### 58. Subtract the mean of each row of a matrix (★★☆) 166 | `hint: mean(axis=,keepdims=)` 167 | #### 59. How to sort an array by the nth column? (★★☆) 168 | `hint: argsort` 169 | #### 60. How to tell if a given 2D array has null columns? (★★☆) 170 | `hint: any, ~` 171 | #### 61. Find the nearest value from a given value in an array (★★☆) 172 | `hint: np.abs, argmin, flat` 173 | #### 62. Considering two arrays with shape (1,3) and (3,1), how to compute their sum using an iterator? (★★☆) 174 | `hint: np.nditer` 175 | #### 63. Create an array class that has a name attribute (★★☆) 176 | `hint: class method` 177 | #### 64. Consider a given vector, how to add 1 to each element indexed by a second vector (be careful with repeated indices)? (★★★) 178 | `hint: np.bincount | np.add.at` 179 | #### 65. How to accumulate elements of a vector (X) to an array (F) based on an index list (I)? (★★★) 180 | `hint: np.bincount` 181 | #### 66. Considering a (w,h,3) image of (dtype=ubyte), compute the number of unique colors (★★☆) 182 | `hint: np.unique` 183 | #### 67. Considering a four dimensions array, how to get sum over the last two axis at once? (★★★) 184 | `hint: sum(axis=(-2,-1))` 185 | #### 68. Considering a one-dimensional vector D, how to compute means of subsets of D using a vector S of same size describing subset indices? (★★★) 186 | `hint: np.bincount` 187 | #### 69. How to get the diagonal of a dot product? (★★★) 188 | `hint: np.diag` 189 | #### 70. Consider the vector [1, 2, 3, 4, 5], how to build a new vector with 3 consecutive zeros interleaved between each value? (★★★) 190 | `hint: array[::4]` 191 | #### 71. Consider an array of dimension (5,5,3), how to mulitply it by an array with dimensions (5,5)? (★★★) 192 | `hint: array[:, :, None]` 193 | #### 72. How to swap two rows of an array? (★★★) 194 | `hint: array[[]] = array[[]]` 195 | #### 73. Consider a set of 10 triplets describing 10 triangles (with shared vertices), find the set of unique line segments composing all the triangles (★★★) 196 | `hint: repeat, np.roll, np.sort, view, np.unique` 197 | #### 74. Given a sorted array C that corresponds to a bincount, how to produce an array A such that np.bincount(A) == C? (★★★) 198 | `hint: np.repeat` 199 | #### 75. How to compute averages using a sliding window over an array? (★★★) 200 | `hint: np.cumsum, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 201 | #### 76. Consider a one-dimensional array Z, build a two-dimensional array whose first row is (Z[0],Z[1],Z[2]) and each subsequent row is shifted by 1 (last row should be (Z[-3],Z[-2],Z[-1]) (★★★) 202 | `hint: from numpy.lib import stride_tricks, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 203 | #### 77. How to negate a boolean, or to change the sign of a float inplace? (★★★) 204 | `hint: np.logical_not, np.negative` 205 | #### 78. Consider 2 sets of points P0,P1 describing lines (2d) and a point p, how to compute distance from p to each line i (P0[i],P1[i])? (★★★) 206 | `No hints provided...` 207 | #### 79. Consider 2 sets of points P0,P1 describing lines (2d) and a set of points P, how to compute distance from each point j (P[j]) to each line i (P0[i],P1[i])? (★★★) 208 | `No hints provided...` 209 | #### 80. Consider an arbitrary array, write a function that extract a subpart with a fixed shape and centered on a given element (pad with a `fill` value when necessary) (★★★) 210 | `hint: minimum maximum` 211 | #### 81. Consider an array Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], how to generate an array R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]]? (★★★) 212 | `hint: stride_tricks.as_strided, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 213 | #### 82. Compute a matrix rank (★★★) 214 | `hint: np.linalg.svd, np.linalg.matrix_rank` 215 | #### 83. How to find the most frequent value in an array? 216 | `hint: np.bincount, argmax` 217 | #### 84. Extract all the contiguous 3x3 blocks from a random 10x10 matrix (★★★) 218 | `hint: stride_tricks.as_strided, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 219 | #### 85. Create a 2D array subclass such that Z[i,j] == Z[j,i] (★★★) 220 | `hint: class method` 221 | #### 86. Consider a set of p matrices with shape (n,n) and a set of p vectors with shape (n,1). How to compute the sum of of the p matrix products at once? (result has shape (n,1)) (★★★) 222 | `hint: np.tensordot` 223 | #### 87. Consider a 16x16 array, how to get the block-sum (block size is 4x4)? (★★★) 224 | `hint: np.add.reduceat, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 225 | #### 88. How to implement the Game of Life using numpy arrays? (★★★) 226 | `No hints provided...` 227 | #### 89. How to get the n largest values of an array (★★★) 228 | `hint: np.argsort | np.argpartition` 229 | #### 90. Given an arbitrary number of vectors, build the cartesian product (every combinations of every item) (★★★) 230 | `hint: np.indices` 231 | #### 91. How to create a record array from a regular array? (★★★) 232 | `hint: np.core.records.fromarrays` 233 | #### 92. Consider a large vector Z, compute Z to the power of 3 using 3 different methods (★★★) 234 | `hint: np.power, *, np.einsum` 235 | #### 93. Consider two arrays A and B of shape (8,3) and (2,2). How to find rows of A that contain elements of each row of B regardless of the order of the elements in B? (★★★) 236 | `hint: np.where` 237 | #### 94. Considering a 10x3 matrix, extract rows with unequal values (e.g. [2,2,3]) (★★★) 238 | `No hints provided...` 239 | #### 95. Convert a vector of ints into a matrix binary representation (★★★) 240 | `hint: np.unpackbits` 241 | #### 96. Given a two dimensional array, how to extract unique rows? (★★★) 242 | `hint: np.ascontiguousarray | np.unique` 243 | #### 97. Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function (★★★) 244 | `hint: np.einsum` 245 | #### 98. Considering a path described by two vectors (X,Y), how to sample it using equidistant samples (★★★)? 246 | `hint: np.cumsum, np.interp` 247 | #### 99. Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n. (★★★) 248 | `hint: np.logical_and.reduce, np.mod` 249 | #### 100. Compute bootstrapped 95% confidence intervals for the mean of a 1D array X (i.e., resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means). (★★★) 250 | `hint: np.percentile` -------------------------------------------------------------------------------- /100_Numpy_exercises_with_hints_with_solutions.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # 100 numpy exercises 5 | 6 | This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow 7 | and in the numpy documentation. The goal of this collection is to offer a quick reference for both old 8 | and new users but also to provide a set of exercises for those who teach. 9 | 10 | 11 | If you find an error or think you've a better way to solve some of them, feel 12 | free to open an issue at . 13 | File automatically generated. See the documentation to update questions/answers/hints programmatically. 14 | 15 | #### 1. Import the numpy package under the name `np` (★☆☆) 16 | `hint: import … as` 17 | 18 | ```python 19 | import numpy as np 20 | ``` 21 | #### 2. Print the numpy version and the configuration (★☆☆) 22 | `hint: np.__version__, np.show_config)` 23 | 24 | ```python 25 | print(np.__version__) 26 | np.show_config() 27 | ``` 28 | #### 3. Create a null vector of size 10 (★☆☆) 29 | `hint: np.zeros` 30 | 31 | ```python 32 | Z = np.zeros(10) 33 | print(Z) 34 | ``` 35 | #### 4. How to find the memory size of any array (★☆☆) 36 | `hint: size, itemsize` 37 | 38 | ```python 39 | Z = np.zeros((10,10)) 40 | print("%d bytes" % (Z.size * Z.itemsize)) 41 | ``` 42 | #### 5. How to get the documentation of the numpy add function from the command line? (★☆☆) 43 | `hint: np.info` 44 | 45 | ```python 46 | %run `python -c "import numpy; numpy.info(numpy.add)"` 47 | ``` 48 | #### 6. Create a null vector of size 10 but the fifth value which is 1 (★☆☆) 49 | `hint: array[4]` 50 | 51 | ```python 52 | Z = np.zeros(10) 53 | Z[4] = 1 54 | print(Z) 55 | ``` 56 | #### 7. Create a vector with values ranging from 10 to 49 (★☆☆) 57 | `hint: arange` 58 | 59 | ```python 60 | Z = np.arange(10,50) 61 | print(Z) 62 | ``` 63 | #### 8. Reverse a vector (first element becomes last) (★☆☆) 64 | `hint: array[::-1]` 65 | 66 | ```python 67 | Z = np.arange(50) 68 | Z = Z[::-1] 69 | print(Z) 70 | ``` 71 | #### 9. Create a 3x3 matrix with values ranging from 0 to 8 (★☆☆) 72 | `hint: reshape` 73 | 74 | ```python 75 | Z = np.arange(9).reshape(3, 3) 76 | print(Z) 77 | ``` 78 | #### 10. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆) 79 | `hint: np.nonzero` 80 | 81 | ```python 82 | nz = np.nonzero([1,2,0,0,4,0]) 83 | print(nz) 84 | ``` 85 | #### 11. Create a 3x3 identity matrix (★☆☆) 86 | `hint: np.eye` 87 | 88 | ```python 89 | Z = np.eye(3) 90 | print(Z) 91 | ``` 92 | #### 12. Create a 3x3x3 array with random values (★☆☆) 93 | `hint: np.random.random` 94 | 95 | ```python 96 | Z = np.random.random((3,3,3)) 97 | print(Z) 98 | ``` 99 | #### 13. Create a 10x10 array with random values and find the minimum and maximum values (★☆☆) 100 | `hint: min, max` 101 | 102 | ```python 103 | Z = np.random.random((10,10)) 104 | Zmin, Zmax = Z.min(), Z.max() 105 | print(Zmin, Zmax) 106 | ``` 107 | #### 14. Create a random vector of size 30 and find the mean value (★☆☆) 108 | `hint: mean` 109 | 110 | ```python 111 | Z = np.random.random(30) 112 | m = Z.mean() 113 | print(m) 114 | ``` 115 | #### 15. Create a 2d array with 1 on the border and 0 inside (★☆☆) 116 | `hint: array[1:-1, 1:-1]` 117 | 118 | ```python 119 | Z = np.ones((10,10)) 120 | Z[1:-1,1:-1] = 0 121 | print(Z) 122 | ``` 123 | #### 16. How to add a border (filled with 0's) around an existing array? (★☆☆) 124 | `hint: np.pad` 125 | 126 | ```python 127 | Z = np.ones((5,5)) 128 | Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0) 129 | print(Z) 130 | 131 | # Using fancy indexing 132 | Z[:, [0, -1]] = 0 133 | Z[[0, -1], :] = 0 134 | print(Z) 135 | ``` 136 | #### 17. What is the result of the following expression? (★☆☆) 137 | ```python 138 | 0 * np.nan 139 | np.nan == np.nan 140 | np.inf > np.nan 141 | np.nan - np.nan 142 | np.nan in set([np.nan]) 143 | 0.3 == 3 * 0.1 144 | ``` 145 | `hint: NaN = not a number, inf = infinity` 146 | 147 | ```python 148 | print(0 * np.nan) 149 | print(np.nan == np.nan) 150 | print(np.inf > np.nan) 151 | print(np.nan - np.nan) 152 | print(np.nan in set([np.nan])) 153 | print(0.3 == 3 * 0.1) 154 | ``` 155 | #### 18. Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆) 156 | `hint: np.diag` 157 | 158 | ```python 159 | Z = np.diag(1+np.arange(4),k=-1) 160 | print(Z) 161 | ``` 162 | #### 19. Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆) 163 | `hint: array[::2]` 164 | 165 | ```python 166 | Z = np.zeros((8,8),dtype=int) 167 | Z[1::2,::2] = 1 168 | Z[::2,1::2] = 1 169 | print(Z) 170 | ``` 171 | #### 20. Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element? (★☆☆) 172 | `hint: np.unravel_index` 173 | 174 | ```python 175 | print(np.unravel_index(99,(6,7,8))) 176 | ``` 177 | #### 21. Create a checkerboard 8x8 matrix using the tile function (★☆☆) 178 | `hint: np.tile` 179 | 180 | ```python 181 | Z = np.tile( np.array([[0,1],[1,0]]), (4,4)) 182 | print(Z) 183 | ``` 184 | #### 22. Normalize a 5x5 random matrix (★☆☆) 185 | `hint: (x -mean)/std` 186 | 187 | ```python 188 | Z = np.random.random((5,5)) 189 | Z = (Z - np.mean (Z)) / (np.std (Z)) 190 | print(Z) 191 | ``` 192 | #### 23. Create a custom dtype that describes a color as four unsigned bytes (RGBA) (★☆☆) 193 | `hint: np.dtype` 194 | 195 | ```python 196 | color = np.dtype([("r", np.ubyte), 197 | ("g", np.ubyte), 198 | ("b", np.ubyte), 199 | ("a", np.ubyte)]) 200 | ``` 201 | #### 24. Multiply a 5x3 matrix by a 3x2 matrix (real matrix product) (★☆☆) 202 | `hint:` 203 | 204 | ```python 205 | Z = np.dot(np.ones((5,3)), np.ones((3,2))) 206 | print(Z) 207 | 208 | # Alternative solution, in Python 3.5 and above 209 | Z = np.ones((5,3)) @ np.ones((3,2)) 210 | print(Z) 211 | ``` 212 | #### 25. Given a 1D array, negate all elements which are between 3 and 8, in place. (★☆☆) 213 | `hint: >, <` 214 | 215 | ```python 216 | # Author: Evgeni Burovski 217 | 218 | Z = np.arange(11) 219 | Z[(3 < Z) & (Z < 8)] *= -1 220 | print(Z) 221 | ``` 222 | #### 26. What is the output of the following script? (★☆☆) 223 | ```python 224 | # Author: Jake VanderPlas 225 | 226 | print(sum(range(5),-1)) 227 | from numpy import * 228 | print(sum(range(5),-1)) 229 | ``` 230 | `hint: np.sum` 231 | 232 | ```python 233 | # Author: Jake VanderPlas 234 | 235 | print(sum(range(5),-1)) 236 | from numpy import * 237 | print(sum(range(5),-1)) 238 | ``` 239 | #### 27. Consider an integer vector Z, which of these expressions are legal? (★☆☆) 240 | ```python 241 | Z**Z 242 | 2 << Z >> 2 243 | Z <- Z 244 | 1j*Z 245 | Z/1/1 246 | ZZ 247 | ``` 248 | `No hints provided...` 249 | 250 | ```python 251 | Z**Z 252 | 2 << Z >> 2 253 | Z <- Z 254 | 1j*Z 255 | Z/1/1 256 | ZZ 257 | ``` 258 | #### 28. What are the result of the following expressions? (★☆☆) 259 | ```python 260 | np.array(0) / np.array(0) 261 | np.array(0) // np.array(0) 262 | np.array([np.nan]).astype(int).astype(float) 263 | ``` 264 | `No hints provided...` 265 | 266 | ```python 267 | print(np.array(0) / np.array(0)) 268 | print(np.array(0) // np.array(0)) 269 | print(np.array([np.nan]).astype(int).astype(float)) 270 | ``` 271 | #### 29. How to round away from zero a float array ? (★☆☆) 272 | `hint: np.uniform, np.copysign, np.ceil, np.abs, np.where` 273 | 274 | ```python 275 | # Author: Charles R Harris 276 | 277 | Z = np.random.uniform(-10,+10,10) 278 | print(np.copysign(np.ceil(np.abs(Z)), Z)) 279 | 280 | # More readable but less efficient 281 | print(np.where(Z>0, np.ceil(Z), np.floor(Z))) 282 | ``` 283 | #### 30. How to find common values between two arrays? (★☆☆) 284 | `hint: np.intersect1d` 285 | 286 | ```python 287 | Z1 = np.random.randint(0,10,10) 288 | Z2 = np.random.randint(0,10,10) 289 | print(np.intersect1d(Z1,Z2)) 290 | ``` 291 | #### 31. How to ignore all numpy warnings (not recommended)? (★☆☆) 292 | `hint: np.seterr, np.errstate` 293 | 294 | ```python 295 | # Suicide mode on 296 | defaults = np.seterr(all="ignore") 297 | Z = np.ones(1) / 0 298 | 299 | # Back to sanity 300 | _ = np.seterr(**defaults) 301 | 302 | # Equivalently with a context manager 303 | with np.errstate(all="ignore"): 304 | np.arange(3) / 0 305 | ``` 306 | #### 32. Is the following expressions true? (★☆☆) 307 | ```python 308 | np.sqrt(-1) == np.emath.sqrt(-1) 309 | ``` 310 | `hint: imaginary number` 311 | 312 | ```python 313 | np.sqrt(-1) == np.emath.sqrt(-1) 314 | ``` 315 | #### 33. How to get the dates of yesterday, today and tomorrow? (★☆☆) 316 | `hint: np.datetime64, np.timedelta64` 317 | 318 | ```python 319 | yesterday = np.datetime64('today') - np.timedelta64(1) 320 | today = np.datetime64('today') 321 | tomorrow = np.datetime64('today') + np.timedelta64(1) 322 | ``` 323 | #### 34. How to get all the dates corresponding to the month of July 2016? (★★☆) 324 | `hint: np.arange(dtype=datetime64['D'])` 325 | 326 | ```python 327 | Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]') 328 | print(Z) 329 | ``` 330 | #### 35. How to compute ((A+B)*(-A/2)) in place (without copy)? (★★☆) 331 | `hint: np.add(out=), np.negative(out=), np.multiply(out=), np.divide(out=)` 332 | 333 | ```python 334 | A = np.ones(3)*1 335 | B = np.ones(3)*2 336 | np.add(A,B,out=B) 337 | np.divide(A,2,out=A) 338 | np.negative(A,out=A) 339 | np.multiply(A,B,out=A) 340 | ``` 341 | #### 36. Extract the integer part of a random array of positive numbers using 4 different methods (★★☆) 342 | `hint: %, np.floor, astype, np.trunc` 343 | 344 | ```python 345 | Z = np.random.uniform(0,10,10) 346 | 347 | print(Z - Z%1) 348 | print(Z // 1) 349 | print(np.floor(Z)) 350 | print(Z.astype(int)) 351 | print(np.trunc(Z)) 352 | ``` 353 | #### 37. Create a 5x5 matrix with row values ranging from 0 to 4 (★★☆) 354 | `hint: np.arange` 355 | 356 | ```python 357 | Z = np.zeros((5,5)) 358 | Z += np.arange(5) 359 | print(Z) 360 | 361 | # without broadcasting 362 | Z = np.tile(np.arange(0, 5), (5,1)) 363 | print(Z) 364 | ``` 365 | #### 38. Consider a generator function that generates 10 integers and use it to build an array (★☆☆) 366 | `hint: np.fromiter` 367 | 368 | ```python 369 | def generate(): 370 | for x in range(10): 371 | yield x 372 | Z = np.fromiter(generate(),dtype=float,count=-1) 373 | print(Z) 374 | ``` 375 | #### 39. Create a vector of size 10 with values ranging from 0 to 1, both excluded (★★☆) 376 | `hint: np.linspace` 377 | 378 | ```python 379 | Z = np.linspace(0,1,11,endpoint=False)[1:] 380 | print(Z) 381 | ``` 382 | #### 40. Create a random vector of size 10 and sort it (★★☆) 383 | `hint: sort` 384 | 385 | ```python 386 | Z = np.random.random(10) 387 | Z.sort() 388 | print(Z) 389 | ``` 390 | #### 41. How to sum a small array faster than np.sum? (★★☆) 391 | `hint: np.add.reduce` 392 | 393 | ```python 394 | # Author: Evgeni Burovski 395 | 396 | Z = np.arange(10) 397 | np.add.reduce(Z) 398 | ``` 399 | #### 42. Consider two random array A and B, check if they are equal (★★☆) 400 | `hint: np.allclose, np.array_equal` 401 | 402 | ```python 403 | A = np.random.randint(0,2,5) 404 | B = np.random.randint(0,2,5) 405 | 406 | # Assuming identical shape of the arrays and a tolerance for the comparison of values 407 | equal = np.allclose(A,B) 408 | print(equal) 409 | 410 | # Checking both the shape and the element values, no tolerance (values have to be exactly equal) 411 | equal = np.array_equal(A,B) 412 | print(equal) 413 | ``` 414 | #### 43. Make an array immutable (read-only) (★★☆) 415 | `hint: flags.writeable` 416 | 417 | ```python 418 | Z = np.zeros(10) 419 | Z.flags.writeable = False 420 | Z[0] = 1 421 | ``` 422 | #### 44. Consider a random 10x2 matrix representing cartesian coordinates, convert them to polar coordinates (★★☆) 423 | `hint: np.sqrt, np.arctan2` 424 | 425 | ```python 426 | Z = np.random.random((10,2)) 427 | X,Y = Z[:,0], Z[:,1] 428 | R = np.sqrt(X**2+Y**2) 429 | T = np.arctan2(Y,X) 430 | print(R) 431 | print(T) 432 | ``` 433 | #### 45. Create random vector of size 10 and replace the maximum value by 0 (★★☆) 434 | `hint: argmax` 435 | 436 | ```python 437 | Z = np.random.random(10) 438 | Z[Z.argmax()] = 0 439 | print(Z) 440 | ``` 441 | #### 46. Create a structured array with `x` and `y` coordinates covering the [0,1]x[0,1] area (★★☆) 442 | `hint: np.meshgrid` 443 | 444 | ```python 445 | Z = np.zeros((5,5), [('x',float),('y',float)]) 446 | Z['x'], Z['y'] = np.meshgrid(np.linspace(0,1,5), 447 | np.linspace(0,1,5)) 448 | print(Z) 449 | ``` 450 | #### 47. Given two arrays, X and Y, construct the Cauchy matrix C (Cij =1/(xi - yj)) (★★☆) 451 | `hint: np.subtract.outer` 452 | 453 | ```python 454 | # Author: Evgeni Burovski 455 | 456 | X = np.arange(8) 457 | Y = X + 0.5 458 | C = 1.0 / np.subtract.outer(X, Y) 459 | print(np.linalg.det(C)) 460 | ``` 461 | #### 48. Print the minimum and maximum representable value for each numpy scalar type (★★☆) 462 | `hint: np.iinfo, np.finfo, eps` 463 | 464 | ```python 465 | for dtype in [np.int8, np.int32, np.int64]: 466 | print(np.iinfo(dtype).min) 467 | print(np.iinfo(dtype).max) 468 | for dtype in [np.float32, np.float64]: 469 | print(np.finfo(dtype).min) 470 | print(np.finfo(dtype).max) 471 | print(np.finfo(dtype).eps) 472 | ``` 473 | #### 49. How to print all the values of an array? (★★☆) 474 | `hint: np.set_printoptions` 475 | 476 | ```python 477 | np.set_printoptions(threshold=float("inf")) 478 | Z = np.zeros((40,40)) 479 | print(Z) 480 | ``` 481 | #### 50. How to find the closest value (to a given scalar) in a vector? (★★☆) 482 | `hint: argmin` 483 | 484 | ```python 485 | Z = np.arange(100) 486 | v = np.random.uniform(0,100) 487 | index = (np.abs(Z-v)).argmin() 488 | print(Z[index]) 489 | ``` 490 | #### 51. Create a structured array representing a position (x,y) and a color (r,g,b) (★★☆) 491 | `hint: dtype` 492 | 493 | ```python 494 | Z = np.zeros(10, [ ('position', [ ('x', float, 1), 495 | ('y', float, 1)]), 496 | ('color', [ ('r', float, 1), 497 | ('g', float, 1), 498 | ('b', float, 1)])]) 499 | print(Z) 500 | ``` 501 | #### 52. Consider a random vector with shape (100,2) representing coordinates, find point by point distances (★★☆) 502 | `hint: np.atleast_2d, T, np.sqrt` 503 | 504 | ```python 505 | Z = np.random.random((10,2)) 506 | X,Y = np.atleast_2d(Z[:,0], Z[:,1]) 507 | D = np.sqrt( (X-X.T)**2 + (Y-Y.T)**2) 508 | print(D) 509 | 510 | # Much faster with scipy 511 | import scipy 512 | # Thanks Gavin Heverly-Coulson (#issue 1) 513 | import scipy.spatial 514 | 515 | Z = np.random.random((10,2)) 516 | D = scipy.spatial.distance.cdist(Z,Z) 517 | print(D) 518 | ``` 519 | #### 53. How to convert a float (32 bits) array into an integer (32 bits) in place? 520 | `hint: view and [:] =` 521 | 522 | ```python 523 | # Thanks Vikas (https://stackoverflow.com/a/10622758/5989906) 524 | # & unutbu (https://stackoverflow.com/a/4396247/5989906) 525 | Z = (np.random.rand(10)*100).astype(np.float32) 526 | Y = Z.view(np.int32) 527 | Y[:] = Z 528 | print(Y) 529 | ``` 530 | #### 54. How to read the following file? (★★☆) 531 | ``` 532 | 1, 2, 3, 4, 5 533 | 6, , , 7, 8 534 | , , 9,10,11 535 | ``` 536 | `hint: np.genfromtxt` 537 | 538 | ```python 539 | from io import StringIO 540 | 541 | # Fake file 542 | s = StringIO('''1, 2, 3, 4, 5 543 | 544 | 6, , , 7, 8 545 | 546 | , , 9,10,11 547 | ''') 548 | Z = np.genfromtxt(s, delimiter=",", dtype=np.int) 549 | print(Z) 550 | ``` 551 | #### 55. What is the equivalent of enumerate for numpy arrays? (★★☆) 552 | `hint: np.ndenumerate, np.ndindex` 553 | 554 | ```python 555 | Z = np.arange(9).reshape(3,3) 556 | for index, value in np.ndenumerate(Z): 557 | print(index, value) 558 | for index in np.ndindex(Z.shape): 559 | print(index, Z[index]) 560 | ``` 561 | #### 56. Generate a generic 2D Gaussian-like array (★★☆) 562 | `hint: np.meshgrid, np.exp` 563 | 564 | ```python 565 | X, Y = np.meshgrid(np.linspace(-1,1,10), np.linspace(-1,1,10)) 566 | D = np.sqrt(X*X+Y*Y) 567 | sigma, mu = 1.0, 0.0 568 | G = np.exp(-( (D-mu)**2 / ( 2.0 * sigma**2 ) ) ) 569 | print(G) 570 | ``` 571 | #### 57. How to randomly place p elements in a 2D array? (★★☆) 572 | `hint: np.put, np.random.choice` 573 | 574 | ```python 575 | # Author: Divakar 576 | 577 | n = 10 578 | p = 3 579 | Z = np.zeros((n,n)) 580 | np.put(Z, np.random.choice(range(n*n), p, replace=False),1) 581 | print(Z) 582 | ``` 583 | #### 58. Subtract the mean of each row of a matrix (★★☆) 584 | `hint: mean(axis=,keepdims=)` 585 | 586 | ```python 587 | # Author: Warren Weckesser 588 | 589 | X = np.random.rand(5, 10) 590 | 591 | # Recent versions of numpy 592 | Y = X - X.mean(axis=1, keepdims=True) 593 | 594 | # Older versions of numpy 595 | Y = X - X.mean(axis=1).reshape(-1, 1) 596 | 597 | print(Y) 598 | ``` 599 | #### 59. How to sort an array by the nth column? (★★☆) 600 | `hint: argsort` 601 | 602 | ```python 603 | # Author: Steve Tjoa 604 | 605 | Z = np.random.randint(0,10,(3,3)) 606 | print(Z) 607 | print(Z[Z[:,1].argsort()]) 608 | ``` 609 | #### 60. How to tell if a given 2D array has null columns? (★★☆) 610 | `hint: any, ~` 611 | 612 | ```python 613 | # Author: Warren Weckesser 614 | 615 | # null : 0 616 | Z = np.random.randint(0,3,(3,10)) 617 | print((~Z.any(axis=0)).any()) 618 | 619 | # null : np.nan 620 | Z=np.array([ 621 | [0,1,np.nan], 622 | [1,2,np.nan], 623 | [4,5,np.nan] 624 | ]) 625 | print(np.isnan(Z).all(axis=0)) 626 | ``` 627 | #### 61. Find the nearest value from a given value in an array (★★☆) 628 | `hint: np.abs, argmin, flat` 629 | 630 | ```python 631 | Z = np.random.uniform(0,1,10) 632 | z = 0.5 633 | m = Z.flat[np.abs(Z - z).argmin()] 634 | print(m) 635 | ``` 636 | #### 62. Considering two arrays with shape (1,3) and (3,1), how to compute their sum using an iterator? (★★☆) 637 | `hint: np.nditer` 638 | 639 | ```python 640 | A = np.arange(3).reshape(3,1) 641 | B = np.arange(3).reshape(1,3) 642 | it = np.nditer([A,B,None]) 643 | for x,y,z in it: z[...] = x + y 644 | print(it.operands[2]) 645 | ``` 646 | #### 63. Create an array class that has a name attribute (★★☆) 647 | `hint: class method` 648 | 649 | ```python 650 | class NamedArray(np.ndarray): 651 | def __new__(cls, array, name="no name"): 652 | obj = np.asarray(array).view(cls) 653 | obj.name = name 654 | return obj 655 | def __array_finalize__(self, obj): 656 | if obj is None: return 657 | self.name = getattr(obj, 'name', "no name") 658 | 659 | Z = NamedArray(np.arange(10), "range_10") 660 | print (Z.name) 661 | ``` 662 | #### 64. Consider a given vector, how to add 1 to each element indexed by a second vector (be careful with repeated indices)? (★★★) 663 | `hint: np.bincount | np.add.at` 664 | 665 | ```python 666 | # Author: Brett Olsen 667 | 668 | Z = np.ones(10) 669 | I = np.random.randint(0,len(Z),20) 670 | Z += np.bincount(I, minlength=len(Z)) 671 | print(Z) 672 | 673 | # Another solution 674 | # Author: Bartosz Telenczuk 675 | np.add.at(Z, I, 1) 676 | print(Z) 677 | ``` 678 | #### 65. How to accumulate elements of a vector (X) to an array (F) based on an index list (I)? (★★★) 679 | `hint: np.bincount` 680 | 681 | ```python 682 | # Author: Alan G Isaac 683 | 684 | X = [1,2,3,4,5,6] 685 | I = [1,3,9,3,4,1] 686 | F = np.bincount(I,X) 687 | print(F) 688 | ``` 689 | #### 66. Considering a (w,h,3) image of (dtype=ubyte), compute the number of unique colors (★★☆) 690 | `hint: np.unique` 691 | 692 | ```python 693 | # Author: Fisher Wang 694 | 695 | w, h = 256, 256 696 | I = np.random.randint(0, 4, (h, w, 3)).astype(np.ubyte) 697 | colors = np.unique(I.reshape(-1, 3), axis=0) 698 | n = len(colors) 699 | print(n) 700 | 701 | # Faster version 702 | # Author: Mark Setchell 703 | # https://stackoverflow.com/a/59671950/2836621 704 | 705 | w, h = 256, 256 706 | I = np.random.randint(0,4,(h,w,3), dtype=np.uint8) 707 | 708 | # View each pixel as a single 24-bit integer, rather than three 8-bit bytes 709 | I24 = np.dot(I.astype(np.uint32),[1,256,65536]) 710 | 711 | # Count unique colours 712 | n = len(np.unique(I24)) 713 | print(n) 714 | ``` 715 | #### 67. Considering a four dimensions array, how to get sum over the last two axis at once? (★★★) 716 | `hint: sum(axis=(-2,-1))` 717 | 718 | ```python 719 | A = np.random.randint(0,10,(3,4,3,4)) 720 | # solution by passing a tuple of axes (introduced in numpy 1.7.0) 721 | sum = A.sum(axis=(-2,-1)) 722 | print(sum) 723 | # solution by flattening the last two dimensions into one 724 | # (useful for functions that don't accept tuples for axis argument) 725 | sum = A.reshape(A.shape[:-2] + (-1,)).sum(axis=-1) 726 | print(sum) 727 | ``` 728 | #### 68. Considering a one-dimensional vector D, how to compute means of subsets of D using a vector S of same size describing subset indices? (★★★) 729 | `hint: np.bincount` 730 | 731 | ```python 732 | # Author: Jaime Fernández del Río 733 | 734 | D = np.random.uniform(0,1,100) 735 | S = np.random.randint(0,10,100) 736 | D_sums = np.bincount(S, weights=D) 737 | D_counts = np.bincount(S) 738 | D_means = D_sums / D_counts 739 | print(D_means) 740 | 741 | # Pandas solution as a reference due to more intuitive code 742 | import pandas as pd 743 | print(pd.Series(D).groupby(S).mean()) 744 | ``` 745 | #### 69. How to get the diagonal of a dot product? (★★★) 746 | `hint: np.diag` 747 | 748 | ```python 749 | # Author: Mathieu Blondel 750 | 751 | A = np.random.uniform(0,1,(5,5)) 752 | B = np.random.uniform(0,1,(5,5)) 753 | 754 | # Slow version 755 | np.diag(np.dot(A, B)) 756 | 757 | # Fast version 758 | np.sum(A * B.T, axis=1) 759 | 760 | # Faster version 761 | np.einsum("ij,ji->i", A, B) 762 | ``` 763 | #### 70. Consider the vector [1, 2, 3, 4, 5], how to build a new vector with 3 consecutive zeros interleaved between each value? (★★★) 764 | `hint: array[::4]` 765 | 766 | ```python 767 | # Author: Warren Weckesser 768 | 769 | Z = np.array([1,2,3,4,5]) 770 | nz = 3 771 | Z0 = np.zeros(len(Z) + (len(Z)-1)*(nz)) 772 | Z0[::nz+1] = Z 773 | print(Z0) 774 | ``` 775 | #### 71. Consider an array of dimension (5,5,3), how to mulitply it by an array with dimensions (5,5)? (★★★) 776 | `hint: array[:, :, None]` 777 | 778 | ```python 779 | A = np.ones((5,5,3)) 780 | B = 2*np.ones((5,5)) 781 | print(A * B[:,:,None]) 782 | ``` 783 | #### 72. How to swap two rows of an array? (★★★) 784 | `hint: array[[]] = array[[]]` 785 | 786 | ```python 787 | # Author: Eelco Hoogendoorn 788 | 789 | A = np.arange(25).reshape(5,5) 790 | A[[0,1]] = A[[1,0]] 791 | print(A) 792 | ``` 793 | #### 73. Consider a set of 10 triplets describing 10 triangles (with shared vertices), find the set of unique line segments composing all the triangles (★★★) 794 | `hint: repeat, np.roll, np.sort, view, np.unique` 795 | 796 | ```python 797 | # Author: Nicolas P. Rougier 798 | 799 | faces = np.random.randint(0,100,(10,3)) 800 | F = np.roll(faces.repeat(2,axis=1),-1,axis=1) 801 | F = F.reshape(len(F)*3,2) 802 | F = np.sort(F,axis=1) 803 | G = F.view( dtype=[('p0',F.dtype),('p1',F.dtype)] ) 804 | G = np.unique(G) 805 | print(G) 806 | ``` 807 | #### 74. Given a sorted array C that corresponds to a bincount, how to produce an array A such that np.bincount(A) == C? (★★★) 808 | `hint: np.repeat` 809 | 810 | ```python 811 | # Author: Jaime Fernández del Río 812 | 813 | C = np.bincount([1,1,2,3,4,4,6]) 814 | A = np.repeat(np.arange(len(C)), C) 815 | print(A) 816 | ``` 817 | #### 75. How to compute averages using a sliding window over an array? (★★★) 818 | `hint: np.cumsum, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 819 | 820 | ```python 821 | # Author: Jaime Fernández del Río 822 | 823 | def moving_average(a, n=3) : 824 | ret = np.cumsum(a, dtype=float) 825 | ret[n:] = ret[n:] - ret[:-n] 826 | return ret[n - 1:] / n 827 | Z = np.arange(20) 828 | print(moving_average(Z, n=3)) 829 | 830 | # Author: Jeff Luo (@Jeff1999) 831 | # make sure your NumPy >= 1.20.0 832 | 833 | from numpy.lib.stride_tricks import sliding_window_view 834 | 835 | Z = np.arange(20) 836 | print(sliding_window_view(Z, window_shape=3).mean(axis=-1)) 837 | ``` 838 | #### 76. Consider a one-dimensional array Z, build a two-dimensional array whose first row is (Z[0],Z[1],Z[2]) and each subsequent row is shifted by 1 (last row should be (Z[-3],Z[-2],Z[-1]) (★★★) 839 | `hint: from numpy.lib import stride_tricks, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 840 | 841 | ```python 842 | # Author: Joe Kington / Erik Rigtorp 843 | from numpy.lib import stride_tricks 844 | 845 | def rolling(a, window): 846 | shape = (a.size - window + 1, window) 847 | strides = (a.strides[0], a.strides[0]) 848 | return stride_tricks.as_strided(a, shape=shape, strides=strides) 849 | Z = rolling(np.arange(10), 3) 850 | print(Z) 851 | 852 | # Author: Jeff Luo (@Jeff1999) 853 | 854 | Z = np.arange(10) 855 | print(sliding_window_view(Z, window_shape=3)) 856 | ``` 857 | #### 77. How to negate a boolean, or to change the sign of a float inplace? (★★★) 858 | `hint: np.logical_not, np.negative` 859 | 860 | ```python 861 | # Author: Nathaniel J. Smith 862 | 863 | Z = np.random.randint(0,2,100) 864 | np.logical_not(Z, out=Z) 865 | 866 | Z = np.random.uniform(-1.0,1.0,100) 867 | np.negative(Z, out=Z) 868 | ``` 869 | #### 78. Consider 2 sets of points P0,P1 describing lines (2d) and a point p, how to compute distance from p to each line i (P0[i],P1[i])? (★★★) 870 | `No hints provided...` 871 | 872 | ```python 873 | def distance(P0, P1, p): 874 | T = P1 - P0 875 | L = (T**2).sum(axis=1) 876 | U = -((P0[:,0]-p[...,0])*T[:,0] + (P0[:,1]-p[...,1])*T[:,1]) / L 877 | U = U.reshape(len(U),1) 878 | D = P0 + U*T - p 879 | return np.sqrt((D**2).sum(axis=1)) 880 | 881 | P0 = np.random.uniform(-10,10,(10,2)) 882 | P1 = np.random.uniform(-10,10,(10,2)) 883 | p = np.random.uniform(-10,10,( 1,2)) 884 | print(distance(P0, P1, p)) 885 | ``` 886 | #### 79. Consider 2 sets of points P0,P1 describing lines (2d) and a set of points P, how to compute distance from each point j (P[j]) to each line i (P0[i],P1[i])? (★★★) 887 | `No hints provided...` 888 | 889 | ```python 890 | # Author: Italmassov Kuanysh 891 | 892 | # based on distance function from previous question 893 | P0 = np.random.uniform(-10, 10, (10,2)) 894 | P1 = np.random.uniform(-10,10,(10,2)) 895 | p = np.random.uniform(-10, 10, (10,2)) 896 | print(np.array([distance(P0,P1,p_i) for p_i in p])) 897 | ``` 898 | #### 80. Consider an arbitrary array, write a function that extract a subpart with a fixed shape and centered on a given element (pad with a `fill` value when necessary) (★★★) 899 | `hint: minimum maximum` 900 | 901 | ```python 902 | # Author: Nicolas Rougier 903 | 904 | Z = np.random.randint(0,10,(10,10)) 905 | shape = (5,5) 906 | fill = 0 907 | position = (1,1) 908 | 909 | R = np.ones(shape, dtype=Z.dtype)*fill 910 | P = np.array(list(position)).astype(int) 911 | Rs = np.array(list(R.shape)).astype(int) 912 | Zs = np.array(list(Z.shape)).astype(int) 913 | 914 | R_start = np.zeros((len(shape),)).astype(int) 915 | R_stop = np.array(list(shape)).astype(int) 916 | Z_start = (P-Rs//2) 917 | Z_stop = (P+Rs//2)+Rs%2 918 | 919 | R_start = (R_start - np.minimum(Z_start,0)).tolist() 920 | Z_start = (np.maximum(Z_start,0)).tolist() 921 | R_stop = np.maximum(R_start, (R_stop - np.maximum(Z_stop-Zs,0))).tolist() 922 | Z_stop = (np.minimum(Z_stop,Zs)).tolist() 923 | 924 | r = [slice(start,stop) for start,stop in zip(R_start,R_stop)] 925 | z = [slice(start,stop) for start,stop in zip(Z_start,Z_stop)] 926 | R[r] = Z[z] 927 | print(Z) 928 | print(R) 929 | ``` 930 | #### 81. Consider an array Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], how to generate an array R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]]? (★★★) 931 | `hint: stride_tricks.as_strided, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 932 | 933 | ```python 934 | # Author: Stefan van der Walt 935 | 936 | Z = np.arange(1,15,dtype=np.uint32) 937 | R = stride_tricks.as_strided(Z,(11,4),(4,4)) 938 | print(R) 939 | 940 | # Author: Jeff Luo (@Jeff1999) 941 | 942 | Z = np.arange(1, 15, dtype=np.uint32) 943 | print(sliding_window_view(Z, window_shape=4)) 944 | ``` 945 | #### 82. Compute a matrix rank (★★★) 946 | `hint: np.linalg.svd, np.linalg.matrix_rank` 947 | 948 | ```python 949 | # Author: Stefan van der Walt 950 | 951 | Z = np.random.uniform(0,1,(10,10)) 952 | U, S, V = np.linalg.svd(Z) # Singular Value Decomposition 953 | rank = np.sum(S > 1e-10) 954 | print(rank) 955 | 956 | # alternative solution: 957 | # Author: Jeff Luo (@Jeff1999) 958 | 959 | rank = np.linalg.matrix_rank(Z) 960 | print(rank) 961 | ``` 962 | #### 83. How to find the most frequent value in an array? 963 | `hint: np.bincount, argmax` 964 | 965 | ```python 966 | Z = np.random.randint(0,10,50) 967 | print(np.bincount(Z).argmax()) 968 | ``` 969 | #### 84. Extract all the contiguous 3x3 blocks from a random 10x10 matrix (★★★) 970 | `hint: stride_tricks.as_strided, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 971 | 972 | ```python 973 | # Author: Chris Barker 974 | 975 | Z = np.random.randint(0,5,(10,10)) 976 | n = 3 977 | i = 1 + (Z.shape[0]-3) 978 | j = 1 + (Z.shape[1]-3) 979 | C = stride_tricks.as_strided(Z, shape=(i, j, n, n), strides=Z.strides + Z.strides) 980 | print(C) 981 | 982 | # Author: Jeff Luo (@Jeff1999) 983 | 984 | Z = np.random.randint(0,5,(10,10)) 985 | print(sliding_window_view(Z, window_shape=(3, 3))) 986 | ``` 987 | #### 85. Create a 2D array subclass such that Z[i,j] == Z[j,i] (★★★) 988 | `hint: class method` 989 | 990 | ```python 991 | # Author: Eric O. Lebigot 992 | # Note: only works for 2d array and value setting using indices 993 | 994 | class Symetric(np.ndarray): 995 | def __setitem__(self, index, value): 996 | i,j = index 997 | super(Symetric, self).__setitem__((i,j), value) 998 | super(Symetric, self).__setitem__((j,i), value) 999 | 1000 | def symetric(Z): 1001 | return np.asarray(Z + Z.T - np.diag(Z.diagonal())).view(Symetric) 1002 | 1003 | S = symetric(np.random.randint(0,10,(5,5))) 1004 | S[2,3] = 42 1005 | print(S) 1006 | ``` 1007 | #### 86. Consider a set of p matrices with shape (n,n) and a set of p vectors with shape (n,1). How to compute the sum of of the p matrix products at once? (result has shape (n,1)) (★★★) 1008 | `hint: np.tensordot` 1009 | 1010 | ```python 1011 | # Author: Stefan van der Walt 1012 | 1013 | p, n = 10, 20 1014 | M = np.ones((p,n,n)) 1015 | V = np.ones((p,n,1)) 1016 | S = np.tensordot(M, V, axes=[[0, 2], [0, 1]]) 1017 | print(S) 1018 | 1019 | # It works, because: 1020 | # M is (p,n,n) 1021 | # V is (p,n,1) 1022 | # Thus, summing over the paired axes 0 and 0 (of M and V independently), 1023 | # and 2 and 1, to remain with a (n,1) vector. 1024 | ``` 1025 | #### 87. Consider a 16x16 array, how to get the block-sum (block size is 4x4)? (★★★) 1026 | `hint: np.add.reduceat, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0)` 1027 | 1028 | ```python 1029 | # Author: Robert Kern 1030 | 1031 | Z = np.ones((16,16)) 1032 | k = 4 1033 | S = np.add.reduceat(np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0), 1034 | np.arange(0, Z.shape[1], k), axis=1) 1035 | print(S) 1036 | 1037 | # alternative solution: 1038 | # Author: Sebastian Wallkötter (@FirefoxMetzger) 1039 | 1040 | Z = np.ones((16,16)) 1041 | k = 4 1042 | 1043 | windows = np.lib.stride_tricks.sliding_window_view(Z, (k, k)) 1044 | S = windows[::k, ::k, ...].sum(axis=(-2, -1)) 1045 | 1046 | # Author: Jeff Luo (@Jeff1999) 1047 | 1048 | Z = np.ones((16, 16)) 1049 | k = 4 1050 | print(sliding_window_view(Z, window_shape=(k, k))[::k, ::k].sum(axis=(-2, -1))) 1051 | ``` 1052 | #### 88. How to implement the Game of Life using numpy arrays? (★★★) 1053 | `No hints provided...` 1054 | 1055 | ```python 1056 | # Author: Nicolas Rougier 1057 | 1058 | def iterate(Z): 1059 | # Count neighbours 1060 | N = (Z[0:-2,0:-2] + Z[0:-2,1:-1] + Z[0:-2,2:] + 1061 | Z[1:-1,0:-2] + Z[1:-1,2:] + 1062 | Z[2: ,0:-2] + Z[2: ,1:-1] + Z[2: ,2:]) 1063 | 1064 | # Apply rules 1065 | birth = (N==3) & (Z[1:-1,1:-1]==0) 1066 | survive = ((N==2) | (N==3)) & (Z[1:-1,1:-1]==1) 1067 | Z[...] = 0 1068 | Z[1:-1,1:-1][birth | survive] = 1 1069 | return Z 1070 | 1071 | Z = np.random.randint(0,2,(50,50)) 1072 | for i in range(100): Z = iterate(Z) 1073 | print(Z) 1074 | ``` 1075 | #### 89. How to get the n largest values of an array (★★★) 1076 | `hint: np.argsort | np.argpartition` 1077 | 1078 | ```python 1079 | Z = np.arange(10000) 1080 | np.random.shuffle(Z) 1081 | n = 5 1082 | 1083 | # Slow 1084 | print (Z[np.argsort(Z)[-n:]]) 1085 | 1086 | # Fast 1087 | print (Z[np.argpartition(-Z,n)[:n]]) 1088 | ``` 1089 | #### 90. Given an arbitrary number of vectors, build the cartesian product (every combinations of every item) (★★★) 1090 | `hint: np.indices` 1091 | 1092 | ```python 1093 | # Author: Stefan Van der Walt 1094 | 1095 | def cartesian(arrays): 1096 | arrays = [np.asarray(a) for a in arrays] 1097 | shape = (len(x) for x in arrays) 1098 | 1099 | ix = np.indices(shape, dtype=int) 1100 | ix = ix.reshape(len(arrays), -1).T 1101 | 1102 | for n, arr in enumerate(arrays): 1103 | ix[:, n] = arrays[n][ix[:, n]] 1104 | 1105 | return ix 1106 | 1107 | print (cartesian(([1, 2, 3], [4, 5], [6, 7]))) 1108 | ``` 1109 | #### 91. How to create a record array from a regular array? (★★★) 1110 | `hint: np.core.records.fromarrays` 1111 | 1112 | ```python 1113 | Z = np.array([("Hello", 2.5, 3), 1114 | ("World", 3.6, 2)]) 1115 | R = np.core.records.fromarrays(Z.T, 1116 | names='col1, col2, col3', 1117 | formats = 'S8, f8, i8') 1118 | print(R) 1119 | ``` 1120 | #### 92. Consider a large vector Z, compute Z to the power of 3 using 3 different methods (★★★) 1121 | `hint: np.power, *, np.einsum` 1122 | 1123 | ```python 1124 | # Author: Ryan G. 1125 | 1126 | x = np.random.rand(int(5e7)) 1127 | 1128 | %timeit np.power(x,3) 1129 | %timeit x*x*x 1130 | %timeit np.einsum('i,i,i->i',x,x,x) 1131 | ``` 1132 | #### 93. Consider two arrays A and B of shape (8,3) and (2,2). How to find rows of A that contain elements of each row of B regardless of the order of the elements in B? (★★★) 1133 | `hint: np.where` 1134 | 1135 | ```python 1136 | # Author: Gabe Schwartz 1137 | 1138 | A = np.random.randint(0,5,(8,3)) 1139 | B = np.random.randint(0,5,(2,2)) 1140 | 1141 | C = (A[..., np.newaxis, np.newaxis] == B) 1142 | rows = np.where(C.any((3,1)).all(1))[0] 1143 | print(rows) 1144 | ``` 1145 | #### 94. Considering a 10x3 matrix, extract rows with unequal values (e.g. [2,2,3]) (★★★) 1146 | `No hints provided...` 1147 | 1148 | ```python 1149 | # Author: Robert Kern 1150 | 1151 | Z = np.random.randint(0,5,(10,3)) 1152 | print(Z) 1153 | # solution for arrays of all dtypes (including string arrays and record arrays) 1154 | E = np.all(Z[:,1:] == Z[:,:-1], axis=1) 1155 | U = Z[~E] 1156 | print(U) 1157 | # soluiton for numerical arrays only, will work for any number of columns in Z 1158 | U = Z[Z.max(axis=1) != Z.min(axis=1),:] 1159 | print(U) 1160 | ``` 1161 | #### 95. Convert a vector of ints into a matrix binary representation (★★★) 1162 | `hint: np.unpackbits` 1163 | 1164 | ```python 1165 | # Author: Warren Weckesser 1166 | 1167 | I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128]) 1168 | B = ((I.reshape(-1,1) & (2**np.arange(8))) != 0).astype(int) 1169 | print(B[:,::-1]) 1170 | 1171 | # Author: Daniel T. McDonald 1172 | 1173 | I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128], dtype=np.uint8) 1174 | print(np.unpackbits(I[:, np.newaxis], axis=1)) 1175 | ``` 1176 | #### 96. Given a two dimensional array, how to extract unique rows? (★★★) 1177 | `hint: np.ascontiguousarray | np.unique` 1178 | 1179 | ```python 1180 | # Author: Jaime Fernández del Río 1181 | 1182 | Z = np.random.randint(0,2,(6,3)) 1183 | T = np.ascontiguousarray(Z).view(np.dtype((np.void, Z.dtype.itemsize * Z.shape[1]))) 1184 | _, idx = np.unique(T, return_index=True) 1185 | uZ = Z[idx] 1186 | print(uZ) 1187 | 1188 | # Author: Andreas Kouzelis 1189 | # NumPy >= 1.13 1190 | uZ = np.unique(Z, axis=0) 1191 | print(uZ) 1192 | ``` 1193 | #### 97. Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function (★★★) 1194 | `hint: np.einsum` 1195 | 1196 | ```python 1197 | # Author: Alex Riley 1198 | # Make sure to read: http://ajcr.net/Basic-guide-to-einsum/ 1199 | 1200 | A = np.random.uniform(0,1,10) 1201 | B = np.random.uniform(0,1,10) 1202 | 1203 | np.einsum('i->', A) # np.sum(A) 1204 | np.einsum('i,i->i', A, B) # A * B 1205 | np.einsum('i,i', A, B) # np.inner(A, B) 1206 | np.einsum('i,j->ij', A, B) # np.outer(A, B) 1207 | ``` 1208 | #### 98. Considering a path described by two vectors (X,Y), how to sample it using equidistant samples (★★★)? 1209 | `hint: np.cumsum, np.interp` 1210 | 1211 | ```python 1212 | # Author: Bas Swinckels 1213 | 1214 | phi = np.arange(0, 10*np.pi, 0.1) 1215 | a = 1 1216 | x = a*phi*np.cos(phi) 1217 | y = a*phi*np.sin(phi) 1218 | 1219 | dr = (np.diff(x)**2 + np.diff(y)**2)**.5 # segment lengths 1220 | r = np.zeros_like(x) 1221 | r[1:] = np.cumsum(dr) # integrate path 1222 | r_int = np.linspace(0, r.max(), 200) # regular spaced path 1223 | x_int = np.interp(r_int, r, x) # integrate path 1224 | y_int = np.interp(r_int, r, y) 1225 | ``` 1226 | #### 99. Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n. (★★★) 1227 | `hint: np.logical_and.reduce, np.mod` 1228 | 1229 | ```python 1230 | # Author: Evgeni Burovski 1231 | 1232 | X = np.asarray([[1.0, 0.0, 3.0, 8.0], 1233 | [2.0, 0.0, 1.0, 1.0], 1234 | [1.5, 2.5, 1.0, 0.0]]) 1235 | n = 4 1236 | M = np.logical_and.reduce(np.mod(X, 1) == 0, axis=-1) 1237 | M &= (X.sum(axis=-1) == n) 1238 | print(X[M]) 1239 | ``` 1240 | #### 100. Compute bootstrapped 95% confidence intervals for the mean of a 1D array X (i.e., resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means). (★★★) 1241 | `hint: np.percentile` 1242 | 1243 | ```python 1244 | # Author: Jessica B. Hamrick 1245 | 1246 | X = np.random.randn(100) # random 1D array 1247 | N = 1000 # number of bootstrap samples 1248 | idx = np.random.randint(0, X.size, (N, X.size)) 1249 | means = X[idx].mean(axis=1) 1250 | confint = np.percentile(means, [2.5, 97.5]) 1251 | print(confint) 1252 | ``` -------------------------------------------------------------------------------- /100_Numpy_exercises_with_solutions.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # 100 numpy exercises 5 | 6 | This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow 7 | and in the numpy documentation. The goal of this collection is to offer a quick reference for both old 8 | and new users but also to provide a set of exercises for those who teach. 9 | 10 | 11 | If you find an error or think you've a better way to solve some of them, feel 12 | free to open an issue at . 13 | File automatically generated. See the documentation to update questions/answers/hints programmatically. 14 | 15 | #### 1. Import the numpy package under the name `np` (★☆☆) 16 | 17 | 18 | ```python 19 | import numpy as np 20 | ``` 21 | #### 2. Print the numpy version and the configuration (★☆☆) 22 | 23 | 24 | ```python 25 | print(np.__version__) 26 | np.show_config() 27 | ``` 28 | #### 3. Create a null vector of size 10 (★☆☆) 29 | 30 | 31 | ```python 32 | Z = np.zeros(10) 33 | print(Z) 34 | ``` 35 | #### 4. How to find the memory size of any array (★☆☆) 36 | 37 | 38 | ```python 39 | Z = np.zeros((10,10)) 40 | print("%d bytes" % (Z.size * Z.itemsize)) 41 | ``` 42 | #### 5. How to get the documentation of the numpy add function from the command line? (★☆☆) 43 | 44 | 45 | ```python 46 | %run `python -c "import numpy; numpy.info(numpy.add)"` 47 | ``` 48 | #### 6. Create a null vector of size 10 but the fifth value which is 1 (★☆☆) 49 | 50 | 51 | ```python 52 | Z = np.zeros(10) 53 | Z[4] = 1 54 | print(Z) 55 | ``` 56 | #### 7. Create a vector with values ranging from 10 to 49 (★☆☆) 57 | 58 | 59 | ```python 60 | Z = np.arange(10,50) 61 | print(Z) 62 | ``` 63 | #### 8. Reverse a vector (first element becomes last) (★☆☆) 64 | 65 | 66 | ```python 67 | Z = np.arange(50) 68 | Z = Z[::-1] 69 | print(Z) 70 | ``` 71 | #### 9. Create a 3x3 matrix with values ranging from 0 to 8 (★☆☆) 72 | 73 | 74 | ```python 75 | Z = np.arange(9).reshape(3, 3) 76 | print(Z) 77 | ``` 78 | #### 10. Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆) 79 | 80 | 81 | ```python 82 | nz = np.nonzero([1,2,0,0,4,0]) 83 | print(nz) 84 | ``` 85 | #### 11. Create a 3x3 identity matrix (★☆☆) 86 | 87 | 88 | ```python 89 | Z = np.eye(3) 90 | print(Z) 91 | ``` 92 | #### 12. Create a 3x3x3 array with random values (★☆☆) 93 | 94 | 95 | ```python 96 | Z = np.random.random((3,3,3)) 97 | print(Z) 98 | ``` 99 | #### 13. Create a 10x10 array with random values and find the minimum and maximum values (★☆☆) 100 | 101 | 102 | ```python 103 | Z = np.random.random((10,10)) 104 | Zmin, Zmax = Z.min(), Z.max() 105 | print(Zmin, Zmax) 106 | ``` 107 | #### 14. Create a random vector of size 30 and find the mean value (★☆☆) 108 | 109 | 110 | ```python 111 | Z = np.random.random(30) 112 | m = Z.mean() 113 | print(m) 114 | ``` 115 | #### 15. Create a 2d array with 1 on the border and 0 inside (★☆☆) 116 | 117 | 118 | ```python 119 | Z = np.ones((10,10)) 120 | Z[1:-1,1:-1] = 0 121 | print(Z) 122 | ``` 123 | #### 16. How to add a border (filled with 0's) around an existing array? (★☆☆) 124 | 125 | 126 | ```python 127 | Z = np.ones((5,5)) 128 | Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0) 129 | print(Z) 130 | 131 | # Using fancy indexing 132 | Z[:, [0, -1]] = 0 133 | Z[[0, -1], :] = 0 134 | print(Z) 135 | ``` 136 | #### 17. What is the result of the following expression? (★☆☆) 137 | ```python 138 | 0 * np.nan 139 | np.nan == np.nan 140 | np.inf > np.nan 141 | np.nan - np.nan 142 | np.nan in set([np.nan]) 143 | 0.3 == 3 * 0.1 144 | ``` 145 | 146 | 147 | ```python 148 | print(0 * np.nan) 149 | print(np.nan == np.nan) 150 | print(np.inf > np.nan) 151 | print(np.nan - np.nan) 152 | print(np.nan in set([np.nan])) 153 | print(0.3 == 3 * 0.1) 154 | ``` 155 | #### 18. Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆) 156 | 157 | 158 | ```python 159 | Z = np.diag(1+np.arange(4),k=-1) 160 | print(Z) 161 | ``` 162 | #### 19. Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆) 163 | 164 | 165 | ```python 166 | Z = np.zeros((8,8),dtype=int) 167 | Z[1::2,::2] = 1 168 | Z[::2,1::2] = 1 169 | print(Z) 170 | ``` 171 | #### 20. Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element? (★☆☆) 172 | 173 | 174 | ```python 175 | print(np.unravel_index(99,(6,7,8))) 176 | ``` 177 | #### 21. Create a checkerboard 8x8 matrix using the tile function (★☆☆) 178 | 179 | 180 | ```python 181 | Z = np.tile( np.array([[0,1],[1,0]]), (4,4)) 182 | print(Z) 183 | ``` 184 | #### 22. Normalize a 5x5 random matrix (★☆☆) 185 | 186 | 187 | ```python 188 | Z = np.random.random((5,5)) 189 | Z = (Z - np.mean (Z)) / (np.std (Z)) 190 | print(Z) 191 | ``` 192 | #### 23. Create a custom dtype that describes a color as four unsigned bytes (RGBA) (★☆☆) 193 | 194 | 195 | ```python 196 | color = np.dtype([("r", np.ubyte), 197 | ("g", np.ubyte), 198 | ("b", np.ubyte), 199 | ("a", np.ubyte)]) 200 | ``` 201 | #### 24. Multiply a 5x3 matrix by a 3x2 matrix (real matrix product) (★☆☆) 202 | 203 | 204 | ```python 205 | Z = np.dot(np.ones((5,3)), np.ones((3,2))) 206 | print(Z) 207 | 208 | # Alternative solution, in Python 3.5 and above 209 | Z = np.ones((5,3)) @ np.ones((3,2)) 210 | print(Z) 211 | ``` 212 | #### 25. Given a 1D array, negate all elements which are between 3 and 8, in place. (★☆☆) 213 | 214 | 215 | ```python 216 | # Author: Evgeni Burovski 217 | 218 | Z = np.arange(11) 219 | Z[(3 < Z) & (Z < 8)] *= -1 220 | print(Z) 221 | ``` 222 | #### 26. What is the output of the following script? (★☆☆) 223 | ```python 224 | # Author: Jake VanderPlas 225 | 226 | print(sum(range(5),-1)) 227 | from numpy import * 228 | print(sum(range(5),-1)) 229 | ``` 230 | 231 | 232 | ```python 233 | # Author: Jake VanderPlas 234 | 235 | print(sum(range(5),-1)) 236 | from numpy import * 237 | print(sum(range(5),-1)) 238 | ``` 239 | #### 27. Consider an integer vector Z, which of these expressions are legal? (★☆☆) 240 | ```python 241 | Z**Z 242 | 2 << Z >> 2 243 | Z <- Z 244 | 1j*Z 245 | Z/1/1 246 | ZZ 247 | ``` 248 | 249 | 250 | ```python 251 | Z**Z 252 | 2 << Z >> 2 253 | Z <- Z 254 | 1j*Z 255 | Z/1/1 256 | ZZ 257 | ``` 258 | #### 28. What are the result of the following expressions? (★☆☆) 259 | ```python 260 | np.array(0) / np.array(0) 261 | np.array(0) // np.array(0) 262 | np.array([np.nan]).astype(int).astype(float) 263 | ``` 264 | 265 | 266 | ```python 267 | print(np.array(0) / np.array(0)) 268 | print(np.array(0) // np.array(0)) 269 | print(np.array([np.nan]).astype(int).astype(float)) 270 | ``` 271 | #### 29. How to round away from zero a float array ? (★☆☆) 272 | 273 | 274 | ```python 275 | # Author: Charles R Harris 276 | 277 | Z = np.random.uniform(-10,+10,10) 278 | print(np.copysign(np.ceil(np.abs(Z)), Z)) 279 | 280 | # More readable but less efficient 281 | print(np.where(Z>0, np.ceil(Z), np.floor(Z))) 282 | ``` 283 | #### 30. How to find common values between two arrays? (★☆☆) 284 | 285 | 286 | ```python 287 | Z1 = np.random.randint(0,10,10) 288 | Z2 = np.random.randint(0,10,10) 289 | print(np.intersect1d(Z1,Z2)) 290 | ``` 291 | #### 31. How to ignore all numpy warnings (not recommended)? (★☆☆) 292 | 293 | 294 | ```python 295 | # Suicide mode on 296 | defaults = np.seterr(all="ignore") 297 | Z = np.ones(1) / 0 298 | 299 | # Back to sanity 300 | _ = np.seterr(**defaults) 301 | 302 | # Equivalently with a context manager 303 | with np.errstate(all="ignore"): 304 | np.arange(3) / 0 305 | ``` 306 | #### 32. Is the following expressions true? (★☆☆) 307 | ```python 308 | np.sqrt(-1) == np.emath.sqrt(-1) 309 | ``` 310 | 311 | 312 | ```python 313 | np.sqrt(-1) == np.emath.sqrt(-1) 314 | ``` 315 | #### 33. How to get the dates of yesterday, today and tomorrow? (★☆☆) 316 | 317 | 318 | ```python 319 | yesterday = np.datetime64('today') - np.timedelta64(1) 320 | today = np.datetime64('today') 321 | tomorrow = np.datetime64('today') + np.timedelta64(1) 322 | ``` 323 | #### 34. How to get all the dates corresponding to the month of July 2016? (★★☆) 324 | 325 | 326 | ```python 327 | Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]') 328 | print(Z) 329 | ``` 330 | #### 35. How to compute ((A+B)*(-A/2)) in place (without copy)? (★★☆) 331 | 332 | 333 | ```python 334 | A = np.ones(3)*1 335 | B = np.ones(3)*2 336 | np.add(A,B,out=B) 337 | np.divide(A,2,out=A) 338 | np.negative(A,out=A) 339 | np.multiply(A,B,out=A) 340 | ``` 341 | #### 36. Extract the integer part of a random array of positive numbers using 4 different methods (★★☆) 342 | 343 | 344 | ```python 345 | Z = np.random.uniform(0,10,10) 346 | 347 | print(Z - Z%1) 348 | print(Z // 1) 349 | print(np.floor(Z)) 350 | print(Z.astype(int)) 351 | print(np.trunc(Z)) 352 | ``` 353 | #### 37. Create a 5x5 matrix with row values ranging from 0 to 4 (★★☆) 354 | 355 | 356 | ```python 357 | Z = np.zeros((5,5)) 358 | Z += np.arange(5) 359 | print(Z) 360 | 361 | # without broadcasting 362 | Z = np.tile(np.arange(0, 5), (5,1)) 363 | print(Z) 364 | ``` 365 | #### 38. Consider a generator function that generates 10 integers and use it to build an array (★☆☆) 366 | 367 | 368 | ```python 369 | def generate(): 370 | for x in range(10): 371 | yield x 372 | Z = np.fromiter(generate(),dtype=float,count=-1) 373 | print(Z) 374 | ``` 375 | #### 39. Create a vector of size 10 with values ranging from 0 to 1, both excluded (★★☆) 376 | 377 | 378 | ```python 379 | Z = np.linspace(0,1,11,endpoint=False)[1:] 380 | print(Z) 381 | ``` 382 | #### 40. Create a random vector of size 10 and sort it (★★☆) 383 | 384 | 385 | ```python 386 | Z = np.random.random(10) 387 | Z.sort() 388 | print(Z) 389 | ``` 390 | #### 41. How to sum a small array faster than np.sum? (★★☆) 391 | 392 | 393 | ```python 394 | # Author: Evgeni Burovski 395 | 396 | Z = np.arange(10) 397 | np.add.reduce(Z) 398 | ``` 399 | #### 42. Consider two random array A and B, check if they are equal (★★☆) 400 | 401 | 402 | ```python 403 | A = np.random.randint(0,2,5) 404 | B = np.random.randint(0,2,5) 405 | 406 | # Assuming identical shape of the arrays and a tolerance for the comparison of values 407 | equal = np.allclose(A,B) 408 | print(equal) 409 | 410 | # Checking both the shape and the element values, no tolerance (values have to be exactly equal) 411 | equal = np.array_equal(A,B) 412 | print(equal) 413 | ``` 414 | #### 43. Make an array immutable (read-only) (★★☆) 415 | 416 | 417 | ```python 418 | Z = np.zeros(10) 419 | Z.flags.writeable = False 420 | Z[0] = 1 421 | ``` 422 | #### 44. Consider a random 10x2 matrix representing cartesian coordinates, convert them to polar coordinates (★★☆) 423 | 424 | 425 | ```python 426 | Z = np.random.random((10,2)) 427 | X,Y = Z[:,0], Z[:,1] 428 | R = np.sqrt(X**2+Y**2) 429 | T = np.arctan2(Y,X) 430 | print(R) 431 | print(T) 432 | ``` 433 | #### 45. Create random vector of size 10 and replace the maximum value by 0 (★★☆) 434 | 435 | 436 | ```python 437 | Z = np.random.random(10) 438 | Z[Z.argmax()] = 0 439 | print(Z) 440 | ``` 441 | #### 46. Create a structured array with `x` and `y` coordinates covering the [0,1]x[0,1] area (★★☆) 442 | 443 | 444 | ```python 445 | Z = np.zeros((5,5), [('x',float),('y',float)]) 446 | Z['x'], Z['y'] = np.meshgrid(np.linspace(0,1,5), 447 | np.linspace(0,1,5)) 448 | print(Z) 449 | ``` 450 | #### 47. Given two arrays, X and Y, construct the Cauchy matrix C (Cij =1/(xi - yj)) (★★☆) 451 | 452 | 453 | ```python 454 | # Author: Evgeni Burovski 455 | 456 | X = np.arange(8) 457 | Y = X + 0.5 458 | C = 1.0 / np.subtract.outer(X, Y) 459 | print(np.linalg.det(C)) 460 | ``` 461 | #### 48. Print the minimum and maximum representable value for each numpy scalar type (★★☆) 462 | 463 | 464 | ```python 465 | for dtype in [np.int8, np.int32, np.int64]: 466 | print(np.iinfo(dtype).min) 467 | print(np.iinfo(dtype).max) 468 | for dtype in [np.float32, np.float64]: 469 | print(np.finfo(dtype).min) 470 | print(np.finfo(dtype).max) 471 | print(np.finfo(dtype).eps) 472 | ``` 473 | #### 49. How to print all the values of an array? (★★☆) 474 | 475 | 476 | ```python 477 | np.set_printoptions(threshold=float("inf")) 478 | Z = np.zeros((40,40)) 479 | print(Z) 480 | ``` 481 | #### 50. How to find the closest value (to a given scalar) in a vector? (★★☆) 482 | 483 | 484 | ```python 485 | Z = np.arange(100) 486 | v = np.random.uniform(0,100) 487 | index = (np.abs(Z-v)).argmin() 488 | print(Z[index]) 489 | ``` 490 | #### 51. Create a structured array representing a position (x,y) and a color (r,g,b) (★★☆) 491 | 492 | 493 | ```python 494 | Z = np.zeros(10, [ ('position', [ ('x', float, 1), 495 | ('y', float, 1)]), 496 | ('color', [ ('r', float, 1), 497 | ('g', float, 1), 498 | ('b', float, 1)])]) 499 | print(Z) 500 | ``` 501 | #### 52. Consider a random vector with shape (100,2) representing coordinates, find point by point distances (★★☆) 502 | 503 | 504 | ```python 505 | Z = np.random.random((10,2)) 506 | X,Y = np.atleast_2d(Z[:,0], Z[:,1]) 507 | D = np.sqrt( (X-X.T)**2 + (Y-Y.T)**2) 508 | print(D) 509 | 510 | # Much faster with scipy 511 | import scipy 512 | # Thanks Gavin Heverly-Coulson (#issue 1) 513 | import scipy.spatial 514 | 515 | Z = np.random.random((10,2)) 516 | D = scipy.spatial.distance.cdist(Z,Z) 517 | print(D) 518 | ``` 519 | #### 53. How to convert a float (32 bits) array into an integer (32 bits) in place? 520 | 521 | 522 | ```python 523 | # Thanks Vikas (https://stackoverflow.com/a/10622758/5989906) 524 | # & unutbu (https://stackoverflow.com/a/4396247/5989906) 525 | Z = (np.random.rand(10)*100).astype(np.float32) 526 | Y = Z.view(np.int32) 527 | Y[:] = Z 528 | print(Y) 529 | ``` 530 | #### 54. How to read the following file? (★★☆) 531 | ``` 532 | 1, 2, 3, 4, 5 533 | 6, , , 7, 8 534 | , , 9,10,11 535 | ``` 536 | 537 | 538 | ```python 539 | from io import StringIO 540 | 541 | # Fake file 542 | s = StringIO('''1, 2, 3, 4, 5 543 | 544 | 6, , , 7, 8 545 | 546 | , , 9,10,11 547 | ''') 548 | Z = np.genfromtxt(s, delimiter=",", dtype=np.int) 549 | print(Z) 550 | ``` 551 | #### 55. What is the equivalent of enumerate for numpy arrays? (★★☆) 552 | 553 | 554 | ```python 555 | Z = np.arange(9).reshape(3,3) 556 | for index, value in np.ndenumerate(Z): 557 | print(index, value) 558 | for index in np.ndindex(Z.shape): 559 | print(index, Z[index]) 560 | ``` 561 | #### 56. Generate a generic 2D Gaussian-like array (★★☆) 562 | 563 | 564 | ```python 565 | X, Y = np.meshgrid(np.linspace(-1,1,10), np.linspace(-1,1,10)) 566 | D = np.sqrt(X*X+Y*Y) 567 | sigma, mu = 1.0, 0.0 568 | G = np.exp(-( (D-mu)**2 / ( 2.0 * sigma**2 ) ) ) 569 | print(G) 570 | ``` 571 | #### 57. How to randomly place p elements in a 2D array? (★★☆) 572 | 573 | 574 | ```python 575 | # Author: Divakar 576 | 577 | n = 10 578 | p = 3 579 | Z = np.zeros((n,n)) 580 | np.put(Z, np.random.choice(range(n*n), p, replace=False),1) 581 | print(Z) 582 | ``` 583 | #### 58. Subtract the mean of each row of a matrix (★★☆) 584 | 585 | 586 | ```python 587 | # Author: Warren Weckesser 588 | 589 | X = np.random.rand(5, 10) 590 | 591 | # Recent versions of numpy 592 | Y = X - X.mean(axis=1, keepdims=True) 593 | 594 | # Older versions of numpy 595 | Y = X - X.mean(axis=1).reshape(-1, 1) 596 | 597 | print(Y) 598 | ``` 599 | #### 59. How to sort an array by the nth column? (★★☆) 600 | 601 | 602 | ```python 603 | # Author: Steve Tjoa 604 | 605 | Z = np.random.randint(0,10,(3,3)) 606 | print(Z) 607 | print(Z[Z[:,1].argsort()]) 608 | ``` 609 | #### 60. How to tell if a given 2D array has null columns? (★★☆) 610 | 611 | 612 | ```python 613 | # Author: Warren Weckesser 614 | 615 | # null : 0 616 | Z = np.random.randint(0,3,(3,10)) 617 | print((~Z.any(axis=0)).any()) 618 | 619 | # null : np.nan 620 | Z=np.array([ 621 | [0,1,np.nan], 622 | [1,2,np.nan], 623 | [4,5,np.nan] 624 | ]) 625 | print(np.isnan(Z).all(axis=0)) 626 | ``` 627 | #### 61. Find the nearest value from a given value in an array (★★☆) 628 | 629 | 630 | ```python 631 | Z = np.random.uniform(0,1,10) 632 | z = 0.5 633 | m = Z.flat[np.abs(Z - z).argmin()] 634 | print(m) 635 | ``` 636 | #### 62. Considering two arrays with shape (1,3) and (3,1), how to compute their sum using an iterator? (★★☆) 637 | 638 | 639 | ```python 640 | A = np.arange(3).reshape(3,1) 641 | B = np.arange(3).reshape(1,3) 642 | it = np.nditer([A,B,None]) 643 | for x,y,z in it: z[...] = x + y 644 | print(it.operands[2]) 645 | ``` 646 | #### 63. Create an array class that has a name attribute (★★☆) 647 | 648 | 649 | ```python 650 | class NamedArray(np.ndarray): 651 | def __new__(cls, array, name="no name"): 652 | obj = np.asarray(array).view(cls) 653 | obj.name = name 654 | return obj 655 | def __array_finalize__(self, obj): 656 | if obj is None: return 657 | self.name = getattr(obj, 'name', "no name") 658 | 659 | Z = NamedArray(np.arange(10), "range_10") 660 | print (Z.name) 661 | ``` 662 | #### 64. Consider a given vector, how to add 1 to each element indexed by a second vector (be careful with repeated indices)? (★★★) 663 | 664 | 665 | ```python 666 | # Author: Brett Olsen 667 | 668 | Z = np.ones(10) 669 | I = np.random.randint(0,len(Z),20) 670 | Z += np.bincount(I, minlength=len(Z)) 671 | print(Z) 672 | 673 | # Another solution 674 | # Author: Bartosz Telenczuk 675 | np.add.at(Z, I, 1) 676 | print(Z) 677 | ``` 678 | #### 65. How to accumulate elements of a vector (X) to an array (F) based on an index list (I)? (★★★) 679 | 680 | 681 | ```python 682 | # Author: Alan G Isaac 683 | 684 | X = [1,2,3,4,5,6] 685 | I = [1,3,9,3,4,1] 686 | F = np.bincount(I,X) 687 | print(F) 688 | ``` 689 | #### 66. Considering a (w,h,3) image of (dtype=ubyte), compute the number of unique colors (★★☆) 690 | 691 | 692 | ```python 693 | # Author: Fisher Wang 694 | 695 | w, h = 256, 256 696 | I = np.random.randint(0, 4, (h, w, 3)).astype(np.ubyte) 697 | colors = np.unique(I.reshape(-1, 3), axis=0) 698 | n = len(colors) 699 | print(n) 700 | 701 | # Faster version 702 | # Author: Mark Setchell 703 | # https://stackoverflow.com/a/59671950/2836621 704 | 705 | w, h = 256, 256 706 | I = np.random.randint(0,4,(h,w,3), dtype=np.uint8) 707 | 708 | # View each pixel as a single 24-bit integer, rather than three 8-bit bytes 709 | I24 = np.dot(I.astype(np.uint32),[1,256,65536]) 710 | 711 | # Count unique colours 712 | n = len(np.unique(I24)) 713 | print(n) 714 | ``` 715 | #### 67. Considering a four dimensions array, how to get sum over the last two axis at once? (★★★) 716 | 717 | 718 | ```python 719 | A = np.random.randint(0,10,(3,4,3,4)) 720 | # solution by passing a tuple of axes (introduced in numpy 1.7.0) 721 | sum = A.sum(axis=(-2,-1)) 722 | print(sum) 723 | # solution by flattening the last two dimensions into one 724 | # (useful for functions that don't accept tuples for axis argument) 725 | sum = A.reshape(A.shape[:-2] + (-1,)).sum(axis=-1) 726 | print(sum) 727 | ``` 728 | #### 68. Considering a one-dimensional vector D, how to compute means of subsets of D using a vector S of same size describing subset indices? (★★★) 729 | 730 | 731 | ```python 732 | # Author: Jaime Fernández del Río 733 | 734 | D = np.random.uniform(0,1,100) 735 | S = np.random.randint(0,10,100) 736 | D_sums = np.bincount(S, weights=D) 737 | D_counts = np.bincount(S) 738 | D_means = D_sums / D_counts 739 | print(D_means) 740 | 741 | # Pandas solution as a reference due to more intuitive code 742 | import pandas as pd 743 | print(pd.Series(D).groupby(S).mean()) 744 | ``` 745 | #### 69. How to get the diagonal of a dot product? (★★★) 746 | 747 | 748 | ```python 749 | # Author: Mathieu Blondel 750 | 751 | A = np.random.uniform(0,1,(5,5)) 752 | B = np.random.uniform(0,1,(5,5)) 753 | 754 | # Slow version 755 | np.diag(np.dot(A, B)) 756 | 757 | # Fast version 758 | np.sum(A * B.T, axis=1) 759 | 760 | # Faster version 761 | np.einsum("ij,ji->i", A, B) 762 | ``` 763 | #### 70. Consider the vector [1, 2, 3, 4, 5], how to build a new vector with 3 consecutive zeros interleaved between each value? (★★★) 764 | 765 | 766 | ```python 767 | # Author: Warren Weckesser 768 | 769 | Z = np.array([1,2,3,4,5]) 770 | nz = 3 771 | Z0 = np.zeros(len(Z) + (len(Z)-1)*(nz)) 772 | Z0[::nz+1] = Z 773 | print(Z0) 774 | ``` 775 | #### 71. Consider an array of dimension (5,5,3), how to mulitply it by an array with dimensions (5,5)? (★★★) 776 | 777 | 778 | ```python 779 | A = np.ones((5,5,3)) 780 | B = 2*np.ones((5,5)) 781 | print(A * B[:,:,None]) 782 | ``` 783 | #### 72. How to swap two rows of an array? (★★★) 784 | 785 | 786 | ```python 787 | # Author: Eelco Hoogendoorn 788 | 789 | A = np.arange(25).reshape(5,5) 790 | A[[0,1]] = A[[1,0]] 791 | print(A) 792 | ``` 793 | #### 73. Consider a set of 10 triplets describing 10 triangles (with shared vertices), find the set of unique line segments composing all the triangles (★★★) 794 | 795 | 796 | ```python 797 | # Author: Nicolas P. Rougier 798 | 799 | faces = np.random.randint(0,100,(10,3)) 800 | F = np.roll(faces.repeat(2,axis=1),-1,axis=1) 801 | F = F.reshape(len(F)*3,2) 802 | F = np.sort(F,axis=1) 803 | G = F.view( dtype=[('p0',F.dtype),('p1',F.dtype)] ) 804 | G = np.unique(G) 805 | print(G) 806 | ``` 807 | #### 74. Given a sorted array C that corresponds to a bincount, how to produce an array A such that np.bincount(A) == C? (★★★) 808 | 809 | 810 | ```python 811 | # Author: Jaime Fernández del Río 812 | 813 | C = np.bincount([1,1,2,3,4,4,6]) 814 | A = np.repeat(np.arange(len(C)), C) 815 | print(A) 816 | ``` 817 | #### 75. How to compute averages using a sliding window over an array? (★★★) 818 | 819 | 820 | ```python 821 | # Author: Jaime Fernández del Río 822 | 823 | def moving_average(a, n=3) : 824 | ret = np.cumsum(a, dtype=float) 825 | ret[n:] = ret[n:] - ret[:-n] 826 | return ret[n - 1:] / n 827 | Z = np.arange(20) 828 | print(moving_average(Z, n=3)) 829 | 830 | # Author: Jeff Luo (@Jeff1999) 831 | # make sure your NumPy >= 1.20.0 832 | 833 | from numpy.lib.stride_tricks import sliding_window_view 834 | 835 | Z = np.arange(20) 836 | print(sliding_window_view(Z, window_shape=3).mean(axis=-1)) 837 | ``` 838 | #### 76. Consider a one-dimensional array Z, build a two-dimensional array whose first row is (Z[0],Z[1],Z[2]) and each subsequent row is shifted by 1 (last row should be (Z[-3],Z[-2],Z[-1]) (★★★) 839 | 840 | 841 | ```python 842 | # Author: Joe Kington / Erik Rigtorp 843 | from numpy.lib import stride_tricks 844 | 845 | def rolling(a, window): 846 | shape = (a.size - window + 1, window) 847 | strides = (a.strides[0], a.strides[0]) 848 | return stride_tricks.as_strided(a, shape=shape, strides=strides) 849 | Z = rolling(np.arange(10), 3) 850 | print(Z) 851 | 852 | # Author: Jeff Luo (@Jeff1999) 853 | 854 | Z = np.arange(10) 855 | print(sliding_window_view(Z, window_shape=3)) 856 | ``` 857 | #### 77. How to negate a boolean, or to change the sign of a float inplace? (★★★) 858 | 859 | 860 | ```python 861 | # Author: Nathaniel J. Smith 862 | 863 | Z = np.random.randint(0,2,100) 864 | np.logical_not(Z, out=Z) 865 | 866 | Z = np.random.uniform(-1.0,1.0,100) 867 | np.negative(Z, out=Z) 868 | ``` 869 | #### 78. Consider 2 sets of points P0,P1 describing lines (2d) and a point p, how to compute distance from p to each line i (P0[i],P1[i])? (★★★) 870 | 871 | 872 | ```python 873 | def distance(P0, P1, p): 874 | T = P1 - P0 875 | L = (T**2).sum(axis=1) 876 | U = -((P0[:,0]-p[...,0])*T[:,0] + (P0[:,1]-p[...,1])*T[:,1]) / L 877 | U = U.reshape(len(U),1) 878 | D = P0 + U*T - p 879 | return np.sqrt((D**2).sum(axis=1)) 880 | 881 | P0 = np.random.uniform(-10,10,(10,2)) 882 | P1 = np.random.uniform(-10,10,(10,2)) 883 | p = np.random.uniform(-10,10,( 1,2)) 884 | print(distance(P0, P1, p)) 885 | ``` 886 | #### 79. Consider 2 sets of points P0,P1 describing lines (2d) and a set of points P, how to compute distance from each point j (P[j]) to each line i (P0[i],P1[i])? (★★★) 887 | 888 | 889 | ```python 890 | # Author: Italmassov Kuanysh 891 | 892 | # based on distance function from previous question 893 | P0 = np.random.uniform(-10, 10, (10,2)) 894 | P1 = np.random.uniform(-10,10,(10,2)) 895 | p = np.random.uniform(-10, 10, (10,2)) 896 | print(np.array([distance(P0,P1,p_i) for p_i in p])) 897 | ``` 898 | #### 80. Consider an arbitrary array, write a function that extract a subpart with a fixed shape and centered on a given element (pad with a `fill` value when necessary) (★★★) 899 | 900 | 901 | ```python 902 | # Author: Nicolas Rougier 903 | 904 | Z = np.random.randint(0,10,(10,10)) 905 | shape = (5,5) 906 | fill = 0 907 | position = (1,1) 908 | 909 | R = np.ones(shape, dtype=Z.dtype)*fill 910 | P = np.array(list(position)).astype(int) 911 | Rs = np.array(list(R.shape)).astype(int) 912 | Zs = np.array(list(Z.shape)).astype(int) 913 | 914 | R_start = np.zeros((len(shape),)).astype(int) 915 | R_stop = np.array(list(shape)).astype(int) 916 | Z_start = (P-Rs//2) 917 | Z_stop = (P+Rs//2)+Rs%2 918 | 919 | R_start = (R_start - np.minimum(Z_start,0)).tolist() 920 | Z_start = (np.maximum(Z_start,0)).tolist() 921 | R_stop = np.maximum(R_start, (R_stop - np.maximum(Z_stop-Zs,0))).tolist() 922 | Z_stop = (np.minimum(Z_stop,Zs)).tolist() 923 | 924 | r = [slice(start,stop) for start,stop in zip(R_start,R_stop)] 925 | z = [slice(start,stop) for start,stop in zip(Z_start,Z_stop)] 926 | R[r] = Z[z] 927 | print(Z) 928 | print(R) 929 | ``` 930 | #### 81. Consider an array Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], how to generate an array R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]]? (★★★) 931 | 932 | 933 | ```python 934 | # Author: Stefan van der Walt 935 | 936 | Z = np.arange(1,15,dtype=np.uint32) 937 | R = stride_tricks.as_strided(Z,(11,4),(4,4)) 938 | print(R) 939 | 940 | # Author: Jeff Luo (@Jeff1999) 941 | 942 | Z = np.arange(1, 15, dtype=np.uint32) 943 | print(sliding_window_view(Z, window_shape=4)) 944 | ``` 945 | #### 82. Compute a matrix rank (★★★) 946 | 947 | 948 | ```python 949 | # Author: Stefan van der Walt 950 | 951 | Z = np.random.uniform(0,1,(10,10)) 952 | U, S, V = np.linalg.svd(Z) # Singular Value Decomposition 953 | rank = np.sum(S > 1e-10) 954 | print(rank) 955 | 956 | # alternative solution: 957 | # Author: Jeff Luo (@Jeff1999) 958 | 959 | rank = np.linalg.matrix_rank(Z) 960 | print(rank) 961 | ``` 962 | #### 83. How to find the most frequent value in an array? 963 | 964 | 965 | ```python 966 | Z = np.random.randint(0,10,50) 967 | print(np.bincount(Z).argmax()) 968 | ``` 969 | #### 84. Extract all the contiguous 3x3 blocks from a random 10x10 matrix (★★★) 970 | 971 | 972 | ```python 973 | # Author: Chris Barker 974 | 975 | Z = np.random.randint(0,5,(10,10)) 976 | n = 3 977 | i = 1 + (Z.shape[0]-3) 978 | j = 1 + (Z.shape[1]-3) 979 | C = stride_tricks.as_strided(Z, shape=(i, j, n, n), strides=Z.strides + Z.strides) 980 | print(C) 981 | 982 | # Author: Jeff Luo (@Jeff1999) 983 | 984 | Z = np.random.randint(0,5,(10,10)) 985 | print(sliding_window_view(Z, window_shape=(3, 3))) 986 | ``` 987 | #### 85. Create a 2D array subclass such that Z[i,j] == Z[j,i] (★★★) 988 | 989 | 990 | ```python 991 | # Author: Eric O. Lebigot 992 | # Note: only works for 2d array and value setting using indices 993 | 994 | class Symetric(np.ndarray): 995 | def __setitem__(self, index, value): 996 | i,j = index 997 | super(Symetric, self).__setitem__((i,j), value) 998 | super(Symetric, self).__setitem__((j,i), value) 999 | 1000 | def symetric(Z): 1001 | return np.asarray(Z + Z.T - np.diag(Z.diagonal())).view(Symetric) 1002 | 1003 | S = symetric(np.random.randint(0,10,(5,5))) 1004 | S[2,3] = 42 1005 | print(S) 1006 | ``` 1007 | #### 86. Consider a set of p matrices with shape (n,n) and a set of p vectors with shape (n,1). How to compute the sum of of the p matrix products at once? (result has shape (n,1)) (★★★) 1008 | 1009 | 1010 | ```python 1011 | # Author: Stefan van der Walt 1012 | 1013 | p, n = 10, 20 1014 | M = np.ones((p,n,n)) 1015 | V = np.ones((p,n,1)) 1016 | S = np.tensordot(M, V, axes=[[0, 2], [0, 1]]) 1017 | print(S) 1018 | 1019 | # It works, because: 1020 | # M is (p,n,n) 1021 | # V is (p,n,1) 1022 | # Thus, summing over the paired axes 0 and 0 (of M and V independently), 1023 | # and 2 and 1, to remain with a (n,1) vector. 1024 | ``` 1025 | #### 87. Consider a 16x16 array, how to get the block-sum (block size is 4x4)? (★★★) 1026 | 1027 | 1028 | ```python 1029 | # Author: Robert Kern 1030 | 1031 | Z = np.ones((16,16)) 1032 | k = 4 1033 | S = np.add.reduceat(np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0), 1034 | np.arange(0, Z.shape[1], k), axis=1) 1035 | print(S) 1036 | 1037 | # alternative solution: 1038 | # Author: Sebastian Wallkötter (@FirefoxMetzger) 1039 | 1040 | Z = np.ones((16,16)) 1041 | k = 4 1042 | 1043 | windows = np.lib.stride_tricks.sliding_window_view(Z, (k, k)) 1044 | S = windows[::k, ::k, ...].sum(axis=(-2, -1)) 1045 | 1046 | # Author: Jeff Luo (@Jeff1999) 1047 | 1048 | Z = np.ones((16, 16)) 1049 | k = 4 1050 | print(sliding_window_view(Z, window_shape=(k, k))[::k, ::k].sum(axis=(-2, -1))) 1051 | ``` 1052 | #### 88. How to implement the Game of Life using numpy arrays? (★★★) 1053 | 1054 | 1055 | ```python 1056 | # Author: Nicolas Rougier 1057 | 1058 | def iterate(Z): 1059 | # Count neighbours 1060 | N = (Z[0:-2,0:-2] + Z[0:-2,1:-1] + Z[0:-2,2:] + 1061 | Z[1:-1,0:-2] + Z[1:-1,2:] + 1062 | Z[2: ,0:-2] + Z[2: ,1:-1] + Z[2: ,2:]) 1063 | 1064 | # Apply rules 1065 | birth = (N==3) & (Z[1:-1,1:-1]==0) 1066 | survive = ((N==2) | (N==3)) & (Z[1:-1,1:-1]==1) 1067 | Z[...] = 0 1068 | Z[1:-1,1:-1][birth | survive] = 1 1069 | return Z 1070 | 1071 | Z = np.random.randint(0,2,(50,50)) 1072 | for i in range(100): Z = iterate(Z) 1073 | print(Z) 1074 | ``` 1075 | #### 89. How to get the n largest values of an array (★★★) 1076 | 1077 | 1078 | ```python 1079 | Z = np.arange(10000) 1080 | np.random.shuffle(Z) 1081 | n = 5 1082 | 1083 | # Slow 1084 | print (Z[np.argsort(Z)[-n:]]) 1085 | 1086 | # Fast 1087 | print (Z[np.argpartition(-Z,n)[:n]]) 1088 | ``` 1089 | #### 90. Given an arbitrary number of vectors, build the cartesian product (every combinations of every item) (★★★) 1090 | 1091 | 1092 | ```python 1093 | # Author: Stefan Van der Walt 1094 | 1095 | def cartesian(arrays): 1096 | arrays = [np.asarray(a) for a in arrays] 1097 | shape = (len(x) for x in arrays) 1098 | 1099 | ix = np.indices(shape, dtype=int) 1100 | ix = ix.reshape(len(arrays), -1).T 1101 | 1102 | for n, arr in enumerate(arrays): 1103 | ix[:, n] = arrays[n][ix[:, n]] 1104 | 1105 | return ix 1106 | 1107 | print (cartesian(([1, 2, 3], [4, 5], [6, 7]))) 1108 | ``` 1109 | #### 91. How to create a record array from a regular array? (★★★) 1110 | 1111 | 1112 | ```python 1113 | Z = np.array([("Hello", 2.5, 3), 1114 | ("World", 3.6, 2)]) 1115 | R = np.core.records.fromarrays(Z.T, 1116 | names='col1, col2, col3', 1117 | formats = 'S8, f8, i8') 1118 | print(R) 1119 | ``` 1120 | #### 92. Consider a large vector Z, compute Z to the power of 3 using 3 different methods (★★★) 1121 | 1122 | 1123 | ```python 1124 | # Author: Ryan G. 1125 | 1126 | x = np.random.rand(int(5e7)) 1127 | 1128 | %timeit np.power(x,3) 1129 | %timeit x*x*x 1130 | %timeit np.einsum('i,i,i->i',x,x,x) 1131 | ``` 1132 | #### 93. Consider two arrays A and B of shape (8,3) and (2,2). How to find rows of A that contain elements of each row of B regardless of the order of the elements in B? (★★★) 1133 | 1134 | 1135 | ```python 1136 | # Author: Gabe Schwartz 1137 | 1138 | A = np.random.randint(0,5,(8,3)) 1139 | B = np.random.randint(0,5,(2,2)) 1140 | 1141 | C = (A[..., np.newaxis, np.newaxis] == B) 1142 | rows = np.where(C.any((3,1)).all(1))[0] 1143 | print(rows) 1144 | ``` 1145 | #### 94. Considering a 10x3 matrix, extract rows with unequal values (e.g. [2,2,3]) (★★★) 1146 | 1147 | 1148 | ```python 1149 | # Author: Robert Kern 1150 | 1151 | Z = np.random.randint(0,5,(10,3)) 1152 | print(Z) 1153 | # solution for arrays of all dtypes (including string arrays and record arrays) 1154 | E = np.all(Z[:,1:] == Z[:,:-1], axis=1) 1155 | U = Z[~E] 1156 | print(U) 1157 | # soluiton for numerical arrays only, will work for any number of columns in Z 1158 | U = Z[Z.max(axis=1) != Z.min(axis=1),:] 1159 | print(U) 1160 | ``` 1161 | #### 95. Convert a vector of ints into a matrix binary representation (★★★) 1162 | 1163 | 1164 | ```python 1165 | # Author: Warren Weckesser 1166 | 1167 | I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128]) 1168 | B = ((I.reshape(-1,1) & (2**np.arange(8))) != 0).astype(int) 1169 | print(B[:,::-1]) 1170 | 1171 | # Author: Daniel T. McDonald 1172 | 1173 | I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128], dtype=np.uint8) 1174 | print(np.unpackbits(I[:, np.newaxis], axis=1)) 1175 | ``` 1176 | #### 96. Given a two dimensional array, how to extract unique rows? (★★★) 1177 | 1178 | 1179 | ```python 1180 | # Author: Jaime Fernández del Río 1181 | 1182 | Z = np.random.randint(0,2,(6,3)) 1183 | T = np.ascontiguousarray(Z).view(np.dtype((np.void, Z.dtype.itemsize * Z.shape[1]))) 1184 | _, idx = np.unique(T, return_index=True) 1185 | uZ = Z[idx] 1186 | print(uZ) 1187 | 1188 | # Author: Andreas Kouzelis 1189 | # NumPy >= 1.13 1190 | uZ = np.unique(Z, axis=0) 1191 | print(uZ) 1192 | ``` 1193 | #### 97. Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function (★★★) 1194 | 1195 | 1196 | ```python 1197 | # Author: Alex Riley 1198 | # Make sure to read: http://ajcr.net/Basic-guide-to-einsum/ 1199 | 1200 | A = np.random.uniform(0,1,10) 1201 | B = np.random.uniform(0,1,10) 1202 | 1203 | np.einsum('i->', A) # np.sum(A) 1204 | np.einsum('i,i->i', A, B) # A * B 1205 | np.einsum('i,i', A, B) # np.inner(A, B) 1206 | np.einsum('i,j->ij', A, B) # np.outer(A, B) 1207 | ``` 1208 | #### 98. Considering a path described by two vectors (X,Y), how to sample it using equidistant samples (★★★)? 1209 | 1210 | 1211 | ```python 1212 | # Author: Bas Swinckels 1213 | 1214 | phi = np.arange(0, 10*np.pi, 0.1) 1215 | a = 1 1216 | x = a*phi*np.cos(phi) 1217 | y = a*phi*np.sin(phi) 1218 | 1219 | dr = (np.diff(x)**2 + np.diff(y)**2)**.5 # segment lengths 1220 | r = np.zeros_like(x) 1221 | r[1:] = np.cumsum(dr) # integrate path 1222 | r_int = np.linspace(0, r.max(), 200) # regular spaced path 1223 | x_int = np.interp(r_int, r, x) # integrate path 1224 | y_int = np.interp(r_int, r, y) 1225 | ``` 1226 | #### 99. Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n. (★★★) 1227 | 1228 | 1229 | ```python 1230 | # Author: Evgeni Burovski 1231 | 1232 | X = np.asarray([[1.0, 0.0, 3.0, 8.0], 1233 | [2.0, 0.0, 1.0, 1.0], 1234 | [1.5, 2.5, 1.0, 0.0]]) 1235 | n = 4 1236 | M = np.logical_and.reduce(np.mod(X, 1) == 0, axis=-1) 1237 | M &= (X.sum(axis=-1) == n) 1238 | print(X[M]) 1239 | ``` 1240 | #### 100. Compute bootstrapped 95% confidence intervals for the mean of a 1D array X (i.e., resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means). (★★★) 1241 | 1242 | 1243 | ```python 1244 | # Author: Jessica B. Hamrick 1245 | 1246 | X = np.random.randn(100) # random 1D array 1247 | N = 1000 # number of bootstrap samples 1248 | idx = np.random.randint(0, X.size, (N, X.size)) 1249 | means = X[idx].mean(axis=1) 1250 | confint = np.percentile(means, [2.5, 97.5]) 1251 | print(confint) 1252 | ``` -------------------------------------------------------------------------------- /100_Numpy_random.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "e06c1964", 6 | "metadata": {}, 7 | "source": [ 8 | "# 100 numpy exercises\n", 9 | "\n", 10 | "This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow\n", 11 | "and in the numpy documentation. The goal of this collection is to offer a quick reference for both old\n", 12 | "and new users but also to provide a set of exercises for those who teach.\n", 13 | "\n", 14 | "\n", 15 | "If you find an error or think you've a better way to solve some of them, feel\n", 16 | "free to open an issue at ." 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "id": "c108c1c4", 22 | "metadata": {}, 23 | "source": [ 24 | "File automatically generated. See the documentation to update questions/answers/hints programmatically." 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "id": "2aefe09b", 30 | "metadata": {}, 31 | "source": [ 32 | "Run the `initialize.py` module, then call a random question with `pick()` an hint towards its solution with\n", 33 | "`hint(n)` and the answer with `answer(n)`, where n is the number of the picked question." 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": null, 39 | "id": "55c8f855", 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "%run initialise.py" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "id": "8f1e8a4a", 50 | "metadata": {}, 51 | "outputs": [], 52 | "source": [ 53 | "pick()" 54 | ] 55 | } 56 | ], 57 | "metadata": {}, 58 | "nbformat": 4, 59 | "nbformat_minor": 5 60 | } 61 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Nicolas P. Rougier 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 100 numpy exercises 2 | 3 | [![Binder](http://mybinder.org/badge.svg)](http://mybinder.org:/repo/rougier/numpy-100/notebooks/100%20Numpy%20exercises.ipynb) 4 | 5 | This is a collection of numpy exercises from numpy mailing list, stack overflow, and numpy documentation. I've also created some problems myself to reach the 100 limit. The goal of this collection is to offer a quick reference for both old and new users but also to provide a set of exercises for those who teach. For extended exercises, make sure to read [From Python to NumPy](http://www.labri.fr/perso/nrougier/from-python-to-numpy/). 6 | 7 | → [Test them on Binder](http://mybinder.org:/repo/rougier/numpy-100/notebooks/100_Numpy_exercises.ipynb) 8 | → [Read them on GitHub](100_Numpy_exercises.md) 9 | 10 | Note: markdown and ipython notebook are created programmatically from the source data in `source/exercises.ktx`. 11 | To modify the content of these files, please change the text in the source and run the `generators.py` module with a python 12 | interpreter with the libraries under `requirements.txt` installed. 13 | 14 | The keyed text format (`ktx`) is a minimal human readable key-values to store text (markdown or others) indexed by keys. 15 | 16 | This work is licensed under the MIT license. 17 | [![DOI](https://zenodo.org/badge/10173/rougier/numpy-100.svg)](https://zenodo.org/badge/latestdoi/10173/rougier/numpy-100) 18 | 19 | 20 | ### Variants in Other Languages 21 | 22 | - **Julia**: [100 Julia Exercises](https://github.com/RoyiAvital/Julia100Exercises). 23 | -------------------------------------------------------------------------------- /generators.py: -------------------------------------------------------------------------------- 1 | import os 2 | import nbformat as nbf 3 | import mdutils 4 | 5 | 6 | def ktx_to_dict(input_file, keystarter='<'): 7 | """ parsing keyed text to a python dictionary. """ 8 | answer = dict() 9 | 10 | with open(input_file, 'r+', encoding='utf-8') as f: 11 | lines = f.readlines() 12 | 13 | k, val = '', '' 14 | for line in lines: 15 | if line.startswith(keystarter): 16 | k = line.replace(keystarter, '').strip() 17 | val = '' 18 | else: 19 | val += line 20 | 21 | if k: 22 | answer.update({k: val.strip()}) 23 | 24 | return answer 25 | 26 | 27 | def dict_to_ktx(input_dict, output_file, keystarter='<'): 28 | """ Store a python dictionary to a keyed text""" 29 | with open(output_file, 'w+') as f: 30 | for k, val in input_dict.items(): 31 | f.write(f'{keystarter} {k}\n') 32 | f.write(f'{val}\n\n') 33 | 34 | 35 | HEADERS = ktx_to_dict(os.path.join('source', 'headers.ktx')) 36 | QHA = ktx_to_dict(os.path.join('source', 'exercises100.ktx')) 37 | 38 | 39 | def create_jupyter_notebook(destination_filename='100_Numpy_exercises.ipynb'): 40 | """ Programmatically create jupyter notebook with the questions (and hints and solutions if required) 41 | saved under source files """ 42 | 43 | # Create cells sequence 44 | nb = nbf.v4.new_notebook() 45 | 46 | nb['cells'] = [] 47 | 48 | # - Add header: 49 | nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["header"])) 50 | nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["sub_header"])) 51 | nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["jupyter_instruction"])) 52 | 53 | # - Add initialisation 54 | nb['cells'].append(nbf.v4.new_code_cell('%run initialise.py')) 55 | 56 | # - Add questions and empty spaces for answers 57 | for n in range(1, 101): 58 | nb['cells'].append(nbf.v4.new_markdown_cell(f'#### {n}. ' + QHA[f'q{n}'])) 59 | nb['cells'].append(nbf.v4.new_code_cell("")) 60 | 61 | # Delete file if one with the same name is found 62 | if os.path.exists(destination_filename): 63 | os.remove(destination_filename) 64 | 65 | # Write sequence to file 66 | nbf.write(nb, destination_filename) 67 | 68 | 69 | def create_jupyter_notebook_random_question(destination_filename='100_Numpy_random.ipynb'): 70 | """ Programmatically create jupyter notebook with the questions (and hints and solutions if required) 71 | saved under source files """ 72 | 73 | # Create cells sequence 74 | nb = nbf.v4.new_notebook() 75 | 76 | nb['cells'] = [] 77 | 78 | # - Add header: 79 | nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["header"])) 80 | nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["sub_header"])) 81 | nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["jupyter_instruction_rand"])) 82 | 83 | # - Add initialisation 84 | nb['cells'].append(nbf.v4.new_code_cell('%run initialise.py')) 85 | nb['cells'].append(nbf.v4.new_code_cell("pick()")) 86 | 87 | # Delete file if one with the same name is found 88 | if os.path.exists(destination_filename): 89 | os.remove(destination_filename) 90 | 91 | # Write sequence to file 92 | nbf.write(nb, destination_filename) 93 | 94 | 95 | def create_markdown(destination_filename='100_Numpy_exercises', with_hints=False, with_solutions=False): 96 | # Create file name 97 | if with_hints: 98 | destination_filename += '_with_hints' 99 | if with_solutions: 100 | destination_filename += '_with_solutions' 101 | 102 | # Initialise file 103 | mdfile = mdutils.MdUtils(file_name=destination_filename) 104 | 105 | # Add headers 106 | mdfile.write(HEADERS["header"] + '\n') 107 | mdfile.write(HEADERS["sub_header"] + '\n') 108 | 109 | # Add questions (and hint or answers if required) 110 | for n in range(1, 101): 111 | mdfile.new_header(title=f"{n}. {QHA[f'q{n}']}", level=4, add_table_of_contents="n") 112 | if with_hints: 113 | mdfile.write(f"`{QHA[f'h{n}']}`") 114 | if with_solutions: 115 | mdfile.insert_code(QHA[f'a{n}'], language='python') 116 | 117 | # Delete file if one with the same name is found 118 | if os.path.exists(destination_filename): 119 | os.remove(destination_filename) 120 | 121 | # Write sequence to file 122 | mdfile.create_md_file() 123 | 124 | 125 | def create_rst(destination_filename, with_ints=False, with_answers=False): 126 | # TODO: use rstdoc python library. 127 | # also see possible integrations with https://github.com/rougier/numpy-100/pull/38 128 | pass 129 | 130 | 131 | if __name__ == '__main__': 132 | create_jupyter_notebook() 133 | create_jupyter_notebook_random_question() 134 | create_markdown() 135 | create_markdown(with_hints=False, with_solutions=True) 136 | create_markdown(with_hints=True, with_solutions=False) 137 | create_markdown(with_hints=True, with_solutions=True) 138 | -------------------------------------------------------------------------------- /initialise.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | import generators as ge 4 | 5 | 6 | def question(n): 7 | print(f'{n}. ' + ge.QHA[f'q{n}']) 8 | 9 | 10 | def hint(n): 11 | print(ge.QHA[f'h{n}']) 12 | 13 | 14 | def answer(n): 15 | print(ge.QHA[f'a{n}']) 16 | 17 | 18 | def pick(): 19 | n = np.random.randint(1, 100) 20 | question(n) 21 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.17.4 2 | pandas==0.25.3 3 | jupyter==1.0.0 4 | jupyterthemes==0.20.0 5 | mdutils==1.0.0 6 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.7.17 2 | -------------------------------------------------------------------------------- /source/exercises100.ktx: -------------------------------------------------------------------------------- 1 | < q1 2 | Import the numpy package under the name `np` (★☆☆) 3 | 4 | < h1 5 | hint: import … as 6 | 7 | < a1 8 | import numpy as np 9 | 10 | < q2 11 | Print the numpy version and the configuration (★☆☆) 12 | 13 | < h2 14 | hint: np.__version__, np.show_config) 15 | 16 | < a2 17 | print(np.__version__) 18 | np.show_config() 19 | 20 | < q3 21 | Create a null vector of size 10 (★☆☆) 22 | 23 | < h3 24 | hint: np.zeros 25 | 26 | < a3 27 | Z = np.zeros(10) 28 | print(Z) 29 | 30 | < q4 31 | How to find the memory size of any array (★☆☆) 32 | 33 | < h4 34 | hint: size, itemsize 35 | 36 | < a4 37 | Z = np.zeros((10,10)) 38 | print("%d bytes" % (Z.size * Z.itemsize)) 39 | 40 | < q5 41 | How to get the documentation of the numpy add function from the command line? (★☆☆) 42 | 43 | < h5 44 | hint: np.info 45 | 46 | < a5 47 | %run `python -c "import numpy; numpy.info(numpy.add)"` 48 | 49 | < q6 50 | Create a null vector of size 10 but the fifth value which is 1 (★☆☆) 51 | 52 | < h6 53 | hint: array[4] 54 | 55 | < a6 56 | Z = np.zeros(10) 57 | Z[4] = 1 58 | print(Z) 59 | 60 | < q7 61 | Create a vector with values ranging from 10 to 49 (★☆☆) 62 | 63 | < h7 64 | hint: arange 65 | 66 | < a7 67 | Z = np.arange(10,50) 68 | print(Z) 69 | 70 | < q8 71 | Reverse a vector (first element becomes last) (★☆☆) 72 | 73 | < h8 74 | hint: array[::-1] 75 | 76 | < a8 77 | Z = np.arange(50) 78 | Z = Z[::-1] 79 | print(Z) 80 | 81 | < q9 82 | Create a 3x3 matrix with values ranging from 0 to 8 (★☆☆) 83 | 84 | < h9 85 | hint: reshape 86 | 87 | < a9 88 | Z = np.arange(9).reshape(3, 3) 89 | print(Z) 90 | 91 | < q10 92 | Find indices of non-zero elements from [1,2,0,0,4,0] (★☆☆) 93 | 94 | < h10 95 | hint: np.nonzero 96 | 97 | < a10 98 | nz = np.nonzero([1,2,0,0,4,0]) 99 | print(nz) 100 | 101 | < q11 102 | Create a 3x3 identity matrix (★☆☆) 103 | 104 | < h11 105 | hint: np.eye 106 | 107 | < a11 108 | Z = np.eye(3) 109 | print(Z) 110 | 111 | < q12 112 | Create a 3x3x3 array with random values (★☆☆) 113 | 114 | < h12 115 | hint: np.random.random 116 | 117 | < a12 118 | Z = np.random.random((3,3,3)) 119 | print(Z) 120 | 121 | < q13 122 | Create a 10x10 array with random values and find the minimum and maximum values (★☆☆) 123 | 124 | < h13 125 | hint: min, max 126 | 127 | < a13 128 | Z = np.random.random((10,10)) 129 | Zmin, Zmax = Z.min(), Z.max() 130 | print(Zmin, Zmax) 131 | 132 | < q14 133 | Create a random vector of size 30 and find the mean value (★☆☆) 134 | 135 | < h14 136 | hint: mean 137 | 138 | < a14 139 | Z = np.random.random(30) 140 | m = Z.mean() 141 | print(m) 142 | 143 | < q15 144 | Create a 2d array with 1 on the border and 0 inside (★☆☆) 145 | 146 | < h15 147 | hint: array[1:-1, 1:-1] 148 | 149 | < a15 150 | Z = np.ones((10,10)) 151 | Z[1:-1,1:-1] = 0 152 | print(Z) 153 | 154 | < q16 155 | How to add a border (filled with 0's) around an existing array? (★☆☆) 156 | 157 | < h16 158 | hint: np.pad 159 | 160 | < a16 161 | Z = np.ones((5,5)) 162 | Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0) 163 | print(Z) 164 | 165 | # Using fancy indexing 166 | Z[:, [0, -1]] = 0 167 | Z[[0, -1], :] = 0 168 | print(Z) 169 | 170 | < q17 171 | What is the result of the following expression? (★☆☆) 172 | ```python 173 | 0 * np.nan 174 | np.nan == np.nan 175 | np.inf > np.nan 176 | np.nan - np.nan 177 | np.nan in set([np.nan]) 178 | 0.3 == 3 * 0.1 179 | ``` 180 | 181 | < h17 182 | hint: NaN = not a number, inf = infinity 183 | 184 | < a17 185 | print(0 * np.nan) 186 | print(np.nan == np.nan) 187 | print(np.inf > np.nan) 188 | print(np.nan - np.nan) 189 | print(np.nan in set([np.nan])) 190 | print(0.3 == 3 * 0.1) 191 | 192 | < q18 193 | Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆) 194 | 195 | < h18 196 | hint: np.diag 197 | 198 | < a18 199 | Z = np.diag(1+np.arange(4),k=-1) 200 | print(Z) 201 | 202 | < q19 203 | Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆) 204 | 205 | < h19 206 | hint: array[::2] 207 | 208 | < a19 209 | Z = np.zeros((8,8),dtype=int) 210 | Z[1::2,::2] = 1 211 | Z[::2,1::2] = 1 212 | print(Z) 213 | 214 | < q20 215 | Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element? (★☆☆) 216 | 217 | < h20 218 | hint: np.unravel_index 219 | 220 | < a20 221 | print(np.unravel_index(99,(6,7,8))) 222 | 223 | < q21 224 | Create a checkerboard 8x8 matrix using the tile function (★☆☆) 225 | 226 | < h21 227 | hint: np.tile 228 | 229 | < a21 230 | Z = np.tile( np.array([[0,1],[1,0]]), (4,4)) 231 | print(Z) 232 | 233 | < q22 234 | Normalize a 5x5 random matrix (★☆☆) 235 | 236 | < h22 237 | hint: (x -mean)/std 238 | 239 | < a22 240 | Z = np.random.random((5,5)) 241 | Z = (Z - np.mean (Z)) / (np.std (Z)) 242 | print(Z) 243 | 244 | < q23 245 | Create a custom dtype that describes a color as four unsigned bytes (RGBA) (★☆☆) 246 | 247 | < h23 248 | hint: np.dtype 249 | 250 | < a23 251 | color = np.dtype([("r", np.ubyte), 252 | ("g", np.ubyte), 253 | ("b", np.ubyte), 254 | ("a", np.ubyte)]) 255 | 256 | < q24 257 | Multiply a 5x3 matrix by a 3x2 matrix (real matrix product) (★☆☆) 258 | 259 | < h24 260 | hint: 261 | 262 | < a24 263 | Z = np.dot(np.ones((5,3)), np.ones((3,2))) 264 | print(Z) 265 | 266 | # Alternative solution, in Python 3.5 and above 267 | Z = np.ones((5,3)) @ np.ones((3,2)) 268 | print(Z) 269 | 270 | < q25 271 | Given a 1D array, negate all elements which are between 3 and 8, in place. (★☆☆) 272 | 273 | < h25 274 | hint: >, < 275 | 276 | < a25 277 | # Author: Evgeni Burovski 278 | 279 | Z = np.arange(11) 280 | Z[(3 < Z) & (Z < 8)] *= -1 281 | print(Z) 282 | 283 | < q26 284 | What is the output of the following script? (★☆☆) 285 | ```python 286 | # Author: Jake VanderPlas 287 | 288 | print(sum(range(5),-1)) 289 | from numpy import * 290 | print(sum(range(5),-1)) 291 | ``` 292 | 293 | < h26 294 | hint: np.sum 295 | 296 | < a26 297 | # Author: Jake VanderPlas 298 | 299 | print(sum(range(5),-1)) 300 | from numpy import * 301 | print(sum(range(5),-1)) 302 | 303 | < q27 304 | Consider an integer vector Z, which of these expressions are legal? (★☆☆) 305 | ```python 306 | Z**Z 307 | 2 << Z >> 2 308 | Z <- Z 309 | 1j*Z 310 | Z/1/1 311 | ZZ 312 | ``` 313 | 314 | < h27 315 | No hints provided... 316 | 317 | < a27 318 | Z**Z 319 | 2 << Z >> 2 320 | Z <- Z 321 | 1j*Z 322 | Z/1/1 323 | ZZ 324 | 325 | < q28 326 | What are the result of the following expressions? (★☆☆) 327 | ```python 328 | np.array(0) / np.array(0) 329 | np.array(0) // np.array(0) 330 | np.array([np.nan]).astype(int).astype(float) 331 | ``` 332 | 333 | < h28 334 | No hints provided... 335 | 336 | < a28 337 | print(np.array(0) / np.array(0)) 338 | print(np.array(0) // np.array(0)) 339 | print(np.array([np.nan]).astype(int).astype(float)) 340 | 341 | < q29 342 | How to round away from zero a float array ? (★☆☆) 343 | 344 | < h29 345 | hint: np.uniform, np.copysign, np.ceil, np.abs, np.where 346 | 347 | < a29 348 | # Author: Charles R Harris 349 | 350 | Z = np.random.uniform(-10,+10,10) 351 | print(np.copysign(np.ceil(np.abs(Z)), Z)) 352 | 353 | # More readable but less efficient 354 | print(np.where(Z>0, np.ceil(Z), np.floor(Z))) 355 | 356 | < q30 357 | How to find common values between two arrays? (★☆☆) 358 | 359 | < h30 360 | hint: np.intersect1d 361 | 362 | < a30 363 | Z1 = np.random.randint(0,10,10) 364 | Z2 = np.random.randint(0,10,10) 365 | print(np.intersect1d(Z1,Z2)) 366 | 367 | < q31 368 | How to ignore all numpy warnings (not recommended)? (★☆☆) 369 | 370 | < h31 371 | hint: np.seterr, np.errstate 372 | 373 | < a31 374 | # Suicide mode on 375 | defaults = np.seterr(all="ignore") 376 | Z = np.ones(1) / 0 377 | 378 | # Back to sanity 379 | _ = np.seterr(**defaults) 380 | 381 | # Equivalently with a context manager 382 | with np.errstate(all="ignore"): 383 | np.arange(3) / 0 384 | 385 | < q32 386 | Is the following expressions true? (★☆☆) 387 | ```python 388 | np.sqrt(-1) == np.emath.sqrt(-1) 389 | ``` 390 | 391 | < h32 392 | hint: imaginary number 393 | 394 | < a32 395 | np.sqrt(-1) == np.emath.sqrt(-1) 396 | 397 | < q33 398 | How to get the dates of yesterday, today and tomorrow? (★☆☆) 399 | 400 | < h33 401 | hint: np.datetime64, np.timedelta64 402 | 403 | < a33 404 | yesterday = np.datetime64('today') - np.timedelta64(1) 405 | today = np.datetime64('today') 406 | tomorrow = np.datetime64('today') + np.timedelta64(1) 407 | 408 | < q34 409 | How to get all the dates corresponding to the month of July 2016? (★★☆) 410 | 411 | < h34 412 | hint: np.arange(dtype=datetime64['D']) 413 | 414 | < a34 415 | Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]') 416 | print(Z) 417 | 418 | < q35 419 | How to compute ((A+B)*(-A/2)) in place (without copy)? (★★☆) 420 | 421 | < h35 422 | hint: np.add(out=), np.negative(out=), np.multiply(out=), np.divide(out=) 423 | 424 | < a35 425 | A = np.ones(3)*1 426 | B = np.ones(3)*2 427 | np.add(A,B,out=B) 428 | np.divide(A,2,out=A) 429 | np.negative(A,out=A) 430 | np.multiply(A,B,out=A) 431 | 432 | < q36 433 | Extract the integer part of a random array of positive numbers using 4 different methods (★★☆) 434 | 435 | < h36 436 | hint: %, np.floor, astype, np.trunc 437 | 438 | < a36 439 | Z = np.random.uniform(0,10,10) 440 | 441 | print(Z - Z%1) 442 | print(Z // 1) 443 | print(np.floor(Z)) 444 | print(Z.astype(int)) 445 | print(np.trunc(Z)) 446 | 447 | < q37 448 | Create a 5x5 matrix with row values ranging from 0 to 4 (★★☆) 449 | 450 | < h37 451 | hint: np.arange 452 | 453 | < a37 454 | Z = np.zeros((5,5)) 455 | Z += np.arange(5) 456 | print(Z) 457 | 458 | # without broadcasting 459 | Z = np.tile(np.arange(0, 5), (5,1)) 460 | print(Z) 461 | 462 | < q38 463 | Consider a generator function that generates 10 integers and use it to build an array (★☆☆) 464 | 465 | < h38 466 | hint: np.fromiter 467 | 468 | < a38 469 | def generate(): 470 | for x in range(10): 471 | yield x 472 | Z = np.fromiter(generate(),dtype=float,count=-1) 473 | print(Z) 474 | 475 | < q39 476 | Create a vector of size 10 with values ranging from 0 to 1, both excluded (★★☆) 477 | 478 | < h39 479 | hint: np.linspace 480 | 481 | < a39 482 | Z = np.linspace(0,1,11,endpoint=False)[1:] 483 | print(Z) 484 | 485 | < q40 486 | Create a random vector of size 10 and sort it (★★☆) 487 | 488 | < h40 489 | hint: sort 490 | 491 | < a40 492 | Z = np.random.random(10) 493 | Z.sort() 494 | print(Z) 495 | 496 | < q41 497 | How to sum a small array faster than np.sum? (★★☆) 498 | 499 | < h41 500 | hint: np.add.reduce 501 | 502 | < a41 503 | # Author: Evgeni Burovski 504 | 505 | Z = np.arange(10) 506 | np.add.reduce(Z) 507 | 508 | < q42 509 | Consider two random array A and B, check if they are equal (★★☆) 510 | 511 | < h42 512 | hint: np.allclose, np.array_equal 513 | 514 | < a42 515 | A = np.random.randint(0,2,5) 516 | B = np.random.randint(0,2,5) 517 | 518 | # Assuming identical shape of the arrays and a tolerance for the comparison of values 519 | equal = np.allclose(A,B) 520 | print(equal) 521 | 522 | # Checking both the shape and the element values, no tolerance (values have to be exactly equal) 523 | equal = np.array_equal(A,B) 524 | print(equal) 525 | 526 | < q43 527 | Make an array immutable (read-only) (★★☆) 528 | 529 | < h43 530 | hint: flags.writeable 531 | 532 | < a43 533 | Z = np.zeros(10) 534 | Z.flags.writeable = False 535 | Z[0] = 1 536 | 537 | < q44 538 | Consider a random 10x2 matrix representing cartesian coordinates, convert them to polar coordinates (★★☆) 539 | 540 | < h44 541 | hint: np.sqrt, np.arctan2 542 | 543 | < a44 544 | Z = np.random.random((10,2)) 545 | X,Y = Z[:,0], Z[:,1] 546 | R = np.sqrt(X**2+Y**2) 547 | T = np.arctan2(Y,X) 548 | print(R) 549 | print(T) 550 | 551 | < q45 552 | Create random vector of size 10 and replace the maximum value by 0 (★★☆) 553 | 554 | < h45 555 | hint: argmax 556 | 557 | < a45 558 | Z = np.random.random(10) 559 | Z[Z.argmax()] = 0 560 | print(Z) 561 | 562 | < q46 563 | Create a structured array with `x` and `y` coordinates covering the [0,1]x[0,1] area (★★☆) 564 | 565 | < h46 566 | hint: np.meshgrid 567 | 568 | < a46 569 | Z = np.zeros((5,5), [('x',float),('y',float)]) 570 | Z['x'], Z['y'] = np.meshgrid(np.linspace(0,1,5), 571 | np.linspace(0,1,5)) 572 | print(Z) 573 | 574 | < q47 575 | Given two arrays, X and Y, construct the Cauchy matrix C (Cij =1/(xi - yj)) (★★☆) 576 | 577 | < h47 578 | hint: np.subtract.outer 579 | 580 | < a47 581 | # Author: Evgeni Burovski 582 | 583 | X = np.arange(8) 584 | Y = X + 0.5 585 | C = 1.0 / np.subtract.outer(X, Y) 586 | print(np.linalg.det(C)) 587 | 588 | < q48 589 | Print the minimum and maximum representable value for each numpy scalar type (★★☆) 590 | 591 | < h48 592 | hint: np.iinfo, np.finfo, eps 593 | 594 | < a48 595 | for dtype in [np.int8, np.int32, np.int64]: 596 | print(np.iinfo(dtype).min) 597 | print(np.iinfo(dtype).max) 598 | for dtype in [np.float32, np.float64]: 599 | print(np.finfo(dtype).min) 600 | print(np.finfo(dtype).max) 601 | print(np.finfo(dtype).eps) 602 | 603 | < q49 604 | How to print all the values of an array? (★★☆) 605 | 606 | < h49 607 | hint: np.set_printoptions 608 | 609 | < a49 610 | np.set_printoptions(threshold=float("inf")) 611 | Z = np.zeros((40,40)) 612 | print(Z) 613 | 614 | < q50 615 | How to find the closest value (to a given scalar) in a vector? (★★☆) 616 | 617 | < h50 618 | hint: argmin 619 | 620 | < a50 621 | Z = np.arange(100) 622 | v = np.random.uniform(0,100) 623 | index = (np.abs(Z-v)).argmin() 624 | print(Z[index]) 625 | 626 | < q51 627 | Create a structured array representing a position (x,y) and a color (r,g,b) (★★☆) 628 | 629 | < h51 630 | hint: dtype 631 | 632 | < a51 633 | Z = np.zeros(10, [ ('position', [ ('x', float, 1), 634 | ('y', float, 1)]), 635 | ('color', [ ('r', float, 1), 636 | ('g', float, 1), 637 | ('b', float, 1)])]) 638 | print(Z) 639 | 640 | < q52 641 | Consider a random vector with shape (100,2) representing coordinates, find point by point distances (★★☆) 642 | 643 | < h52 644 | hint: np.atleast_2d, T, np.sqrt 645 | 646 | < a52 647 | Z = np.random.random((10,2)) 648 | X,Y = np.atleast_2d(Z[:,0], Z[:,1]) 649 | D = np.sqrt( (X-X.T)**2 + (Y-Y.T)**2) 650 | print(D) 651 | 652 | # Much faster with scipy 653 | import scipy 654 | # Thanks Gavin Heverly-Coulson (#issue 1) 655 | import scipy.spatial 656 | 657 | Z = np.random.random((10,2)) 658 | D = scipy.spatial.distance.cdist(Z,Z) 659 | print(D) 660 | 661 | < q53 662 | How to convert a float (32 bits) array into an integer (32 bits) in place? 663 | 664 | < h53 665 | hint: view and [:] = 666 | 667 | < a53 668 | # Thanks Vikas (https://stackoverflow.com/a/10622758/5989906) 669 | # & unutbu (https://stackoverflow.com/a/4396247/5989906) 670 | Z = (np.random.rand(10)*100).astype(np.float32) 671 | Y = Z.view(np.int32) 672 | Y[:] = Z 673 | print(Y) 674 | 675 | < q54 676 | How to read the following file? (★★☆) 677 | ``` 678 | 1, 2, 3, 4, 5 679 | 6, , , 7, 8 680 | , , 9,10,11 681 | ``` 682 | 683 | < h54 684 | hint: np.genfromtxt 685 | 686 | < a54 687 | from io import StringIO 688 | 689 | # Fake file 690 | s = StringIO('''1, 2, 3, 4, 5 691 | 692 | 6, , , 7, 8 693 | 694 | , , 9,10,11 695 | ''') 696 | Z = np.genfromtxt(s, delimiter=",", dtype=np.int) 697 | print(Z) 698 | 699 | < q55 700 | What is the equivalent of enumerate for numpy arrays? (★★☆) 701 | 702 | < h55 703 | hint: np.ndenumerate, np.ndindex 704 | 705 | < a55 706 | Z = np.arange(9).reshape(3,3) 707 | for index, value in np.ndenumerate(Z): 708 | print(index, value) 709 | for index in np.ndindex(Z.shape): 710 | print(index, Z[index]) 711 | 712 | < q56 713 | Generate a generic 2D Gaussian-like array (★★☆) 714 | 715 | < h56 716 | hint: np.meshgrid, np.exp 717 | 718 | < a56 719 | X, Y = np.meshgrid(np.linspace(-1,1,10), np.linspace(-1,1,10)) 720 | D = np.sqrt(X*X+Y*Y) 721 | sigma, mu = 1.0, 0.0 722 | G = np.exp(-( (D-mu)**2 / ( 2.0 * sigma**2 ) ) ) 723 | print(G) 724 | 725 | < q57 726 | How to randomly place p elements in a 2D array? (★★☆) 727 | 728 | < h57 729 | hint: np.put, np.random.choice 730 | 731 | < a57 732 | # Author: Divakar 733 | 734 | n = 10 735 | p = 3 736 | Z = np.zeros((n,n)) 737 | np.put(Z, np.random.choice(range(n*n), p, replace=False),1) 738 | print(Z) 739 | 740 | < q58 741 | Subtract the mean of each row of a matrix (★★☆) 742 | 743 | < h58 744 | hint: mean(axis=,keepdims=) 745 | 746 | < a58 747 | # Author: Warren Weckesser 748 | 749 | X = np.random.rand(5, 10) 750 | 751 | # Recent versions of numpy 752 | Y = X - X.mean(axis=1, keepdims=True) 753 | 754 | # Older versions of numpy 755 | Y = X - X.mean(axis=1).reshape(-1, 1) 756 | 757 | print(Y) 758 | 759 | < q59 760 | How to sort an array by the nth column? (★★☆) 761 | 762 | < h59 763 | hint: argsort 764 | 765 | < a59 766 | # Author: Steve Tjoa 767 | 768 | Z = np.random.randint(0,10,(3,3)) 769 | print(Z) 770 | print(Z[Z[:,1].argsort()]) 771 | 772 | < q60 773 | How to tell if a given 2D array has null columns? (★★☆) 774 | 775 | < h60 776 | hint: any, ~ 777 | 778 | < a60 779 | # Author: Warren Weckesser 780 | 781 | # null : 0 782 | Z = np.random.randint(0,3,(3,10)) 783 | print((~Z.any(axis=0)).any()) 784 | 785 | # null : np.nan 786 | Z=np.array([ 787 | [0,1,np.nan], 788 | [1,2,np.nan], 789 | [4,5,np.nan] 790 | ]) 791 | print(np.isnan(Z).all(axis=0)) 792 | 793 | < q61 794 | Find the nearest value from a given value in an array (★★☆) 795 | 796 | < h61 797 | hint: np.abs, argmin, flat 798 | 799 | < a61 800 | Z = np.random.uniform(0,1,10) 801 | z = 0.5 802 | m = Z.flat[np.abs(Z - z).argmin()] 803 | print(m) 804 | 805 | < q62 806 | Considering two arrays with shape (1,3) and (3,1), how to compute their sum using an iterator? (★★☆) 807 | 808 | < h62 809 | hint: np.nditer 810 | 811 | < a62 812 | A = np.arange(3).reshape(3,1) 813 | B = np.arange(3).reshape(1,3) 814 | it = np.nditer([A,B,None]) 815 | for x,y,z in it: z[...] = x + y 816 | print(it.operands[2]) 817 | 818 | < q63 819 | Create an array class that has a name attribute (★★☆) 820 | 821 | < h63 822 | hint: class method 823 | 824 | < a63 825 | class NamedArray(np.ndarray): 826 | def __new__(cls, array, name="no name"): 827 | obj = np.asarray(array).view(cls) 828 | obj.name = name 829 | return obj 830 | def __array_finalize__(self, obj): 831 | if obj is None: return 832 | self.name = getattr(obj, 'name', "no name") 833 | 834 | Z = NamedArray(np.arange(10), "range_10") 835 | print (Z.name) 836 | 837 | < q64 838 | Consider a given vector, how to add 1 to each element indexed by a second vector (be careful with repeated indices)? (★★★) 839 | 840 | < h64 841 | hint: np.bincount | np.add.at 842 | 843 | < a64 844 | # Author: Brett Olsen 845 | 846 | Z = np.ones(10) 847 | I = np.random.randint(0,len(Z),20) 848 | Z += np.bincount(I, minlength=len(Z)) 849 | print(Z) 850 | 851 | # Another solution 852 | # Author: Bartosz Telenczuk 853 | np.add.at(Z, I, 1) 854 | print(Z) 855 | 856 | < q65 857 | How to accumulate elements of a vector (X) to an array (F) based on an index list (I)? (★★★) 858 | 859 | < h65 860 | hint: np.bincount 861 | 862 | < a65 863 | # Author: Alan G Isaac 864 | 865 | X = [1,2,3,4,5,6] 866 | I = [1,3,9,3,4,1] 867 | F = np.bincount(I,X) 868 | print(F) 869 | 870 | < q66 871 | Considering a (w,h,3) image of (dtype=ubyte), compute the number of unique colors (★★☆) 872 | 873 | < h66 874 | hint: np.unique 875 | 876 | < a66 877 | # Author: Fisher Wang 878 | 879 | w, h = 256, 256 880 | I = np.random.randint(0, 4, (h, w, 3)).astype(np.ubyte) 881 | colors = np.unique(I.reshape(-1, 3), axis=0) 882 | n = len(colors) 883 | print(n) 884 | 885 | # Faster version 886 | # Author: Mark Setchell 887 | # https://stackoverflow.com/a/59671950/2836621 888 | 889 | w, h = 256, 256 890 | I = np.random.randint(0,4,(h,w,3), dtype=np.uint8) 891 | 892 | # View each pixel as a single 24-bit integer, rather than three 8-bit bytes 893 | I24 = np.dot(I.astype(np.uint32),[1,256,65536]) 894 | 895 | # Count unique colours 896 | n = len(np.unique(I24)) 897 | print(n) 898 | 899 | < q67 900 | Considering a four dimensions array, how to get sum over the last two axis at once? (★★★) 901 | 902 | < h67 903 | hint: sum(axis=(-2,-1)) 904 | 905 | < a67 906 | A = np.random.randint(0,10,(3,4,3,4)) 907 | # solution by passing a tuple of axes (introduced in numpy 1.7.0) 908 | sum = A.sum(axis=(-2,-1)) 909 | print(sum) 910 | # solution by flattening the last two dimensions into one 911 | # (useful for functions that don't accept tuples for axis argument) 912 | sum = A.reshape(A.shape[:-2] + (-1,)).sum(axis=-1) 913 | print(sum) 914 | 915 | < q68 916 | Considering a one-dimensional vector D, how to compute means of subsets of D using a vector S of same size describing subset indices? (★★★) 917 | 918 | < h68 919 | hint: np.bincount 920 | 921 | < a68 922 | # Author: Jaime Fernández del Río 923 | 924 | D = np.random.uniform(0,1,100) 925 | S = np.random.randint(0,10,100) 926 | D_sums = np.bincount(S, weights=D) 927 | D_counts = np.bincount(S) 928 | D_means = D_sums / D_counts 929 | print(D_means) 930 | 931 | # Pandas solution as a reference due to more intuitive code 932 | import pandas as pd 933 | print(pd.Series(D).groupby(S).mean()) 934 | 935 | < q69 936 | How to get the diagonal of a dot product? (★★★) 937 | 938 | < h69 939 | hint: np.diag 940 | 941 | < a69 942 | # Author: Mathieu Blondel 943 | 944 | A = np.random.uniform(0,1,(5,5)) 945 | B = np.random.uniform(0,1,(5,5)) 946 | 947 | # Slow version 948 | np.diag(np.dot(A, B)) 949 | 950 | # Fast version 951 | np.sum(A * B.T, axis=1) 952 | 953 | # Faster version 954 | np.einsum("ij,ji->i", A, B) 955 | 956 | < q70 957 | Consider the vector [1, 2, 3, 4, 5], how to build a new vector with 3 consecutive zeros interleaved between each value? (★★★) 958 | 959 | < h70 960 | hint: array[::4] 961 | 962 | < a70 963 | # Author: Warren Weckesser 964 | 965 | Z = np.array([1,2,3,4,5]) 966 | nz = 3 967 | Z0 = np.zeros(len(Z) + (len(Z)-1)*(nz)) 968 | Z0[::nz+1] = Z 969 | print(Z0) 970 | 971 | < q71 972 | Consider an array of dimension (5,5,3), how to mulitply it by an array with dimensions (5,5)? (★★★) 973 | 974 | < h71 975 | hint: array[:, :, None] 976 | 977 | < a71 978 | A = np.ones((5,5,3)) 979 | B = 2*np.ones((5,5)) 980 | print(A * B[:,:,None]) 981 | 982 | < q72 983 | How to swap two rows of an array? (★★★) 984 | 985 | < h72 986 | hint: array[[]] = array[[]] 987 | 988 | < a72 989 | # Author: Eelco Hoogendoorn 990 | 991 | A = np.arange(25).reshape(5,5) 992 | A[[0,1]] = A[[1,0]] 993 | print(A) 994 | 995 | < q73 996 | Consider a set of 10 triplets describing 10 triangles (with shared vertices), find the set of unique line segments composing all the triangles (★★★) 997 | 998 | < h73 999 | hint: repeat, np.roll, np.sort, view, np.unique 1000 | 1001 | < a73 1002 | # Author: Nicolas P. Rougier 1003 | 1004 | faces = np.random.randint(0,100,(10,3)) 1005 | F = np.roll(faces.repeat(2,axis=1),-1,axis=1) 1006 | F = F.reshape(len(F)*3,2) 1007 | F = np.sort(F,axis=1) 1008 | G = F.view( dtype=[('p0',F.dtype),('p1',F.dtype)] ) 1009 | G = np.unique(G) 1010 | print(G) 1011 | 1012 | < q74 1013 | Given a sorted array C that corresponds to a bincount, how to produce an array A such that np.bincount(A) == C? (★★★) 1014 | 1015 | < h74 1016 | hint: np.repeat 1017 | 1018 | < a74 1019 | # Author: Jaime Fernández del Río 1020 | 1021 | C = np.bincount([1,1,2,3,4,4,6]) 1022 | A = np.repeat(np.arange(len(C)), C) 1023 | print(A) 1024 | 1025 | < q75 1026 | How to compute averages using a sliding window over an array? (★★★) 1027 | 1028 | < h75 1029 | hint: np.cumsum, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0) 1030 | 1031 | < a75 1032 | # Author: Jaime Fernández del Río 1033 | 1034 | def moving_average(a, n=3) : 1035 | ret = np.cumsum(a, dtype=float) 1036 | ret[n:] = ret[n:] - ret[:-n] 1037 | return ret[n - 1:] / n 1038 | Z = np.arange(20) 1039 | print(moving_average(Z, n=3)) 1040 | 1041 | # Author: Jeff Luo (@Jeff1999) 1042 | # make sure your NumPy >= 1.20.0 1043 | 1044 | from numpy.lib.stride_tricks import sliding_window_view 1045 | 1046 | Z = np.arange(20) 1047 | print(sliding_window_view(Z, window_shape=3).mean(axis=-1)) 1048 | 1049 | < q76 1050 | Consider a one-dimensional array Z, build a two-dimensional array whose first row is (Z[0],Z[1],Z[2]) and each subsequent row is shifted by 1 (last row should be (Z[-3],Z[-2],Z[-1]) (★★★) 1051 | 1052 | < h76 1053 | hint: from numpy.lib import stride_tricks, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0) 1054 | 1055 | < a76 1056 | # Author: Joe Kington / Erik Rigtorp 1057 | from numpy.lib import stride_tricks 1058 | 1059 | def rolling(a, window): 1060 | shape = (a.size - window + 1, window) 1061 | strides = (a.strides[0], a.strides[0]) 1062 | return stride_tricks.as_strided(a, shape=shape, strides=strides) 1063 | Z = rolling(np.arange(10), 3) 1064 | print(Z) 1065 | 1066 | # Author: Jeff Luo (@Jeff1999) 1067 | 1068 | Z = np.arange(10) 1069 | print(sliding_window_view(Z, window_shape=3)) 1070 | 1071 | < q77 1072 | How to negate a boolean, or to change the sign of a float inplace? (★★★) 1073 | 1074 | < h77 1075 | hint: np.logical_not, np.negative 1076 | 1077 | < a77 1078 | # Author: Nathaniel J. Smith 1079 | 1080 | Z = np.random.randint(0,2,100) 1081 | np.logical_not(Z, out=Z) 1082 | 1083 | Z = np.random.uniform(-1.0,1.0,100) 1084 | np.negative(Z, out=Z) 1085 | 1086 | < q78 1087 | Consider 2 sets of points P0,P1 describing lines (2d) and a point p, how to compute distance from p to each line i (P0[i],P1[i])? (★★★) 1088 | 1089 | < h78 1090 | No hints provided... 1091 | 1092 | < a78 1093 | def distance(P0, P1, p): 1094 | T = P1 - P0 1095 | L = (T**2).sum(axis=1) 1096 | U = -((P0[:,0]-p[...,0])*T[:,0] + (P0[:,1]-p[...,1])*T[:,1]) / L 1097 | U = U.reshape(len(U),1) 1098 | D = P0 + U*T - p 1099 | return np.sqrt((D**2).sum(axis=1)) 1100 | 1101 | P0 = np.random.uniform(-10,10,(10,2)) 1102 | P1 = np.random.uniform(-10,10,(10,2)) 1103 | p = np.random.uniform(-10,10,( 1,2)) 1104 | print(distance(P0, P1, p)) 1105 | 1106 | < q79 1107 | Consider 2 sets of points P0,P1 describing lines (2d) and a set of points P, how to compute distance from each point j (P[j]) to each line i (P0[i],P1[i])? (★★★) 1108 | 1109 | < h79 1110 | No hints provided... 1111 | 1112 | < a79 1113 | # Author: Italmassov Kuanysh 1114 | 1115 | # based on distance function from previous question 1116 | P0 = np.random.uniform(-10, 10, (10,2)) 1117 | P1 = np.random.uniform(-10,10,(10,2)) 1118 | p = np.random.uniform(-10, 10, (10,2)) 1119 | print(np.array([distance(P0,P1,p_i) for p_i in p])) 1120 | 1121 | < q80 1122 | Consider an arbitrary array, write a function that extract a subpart with a fixed shape and centered on a given element (pad with a `fill` value when necessary) (★★★) 1123 | 1124 | < h80 1125 | hint: minimum maximum 1126 | 1127 | < a80 1128 | # Author: Nicolas Rougier 1129 | 1130 | Z = np.random.randint(0,10,(10,10)) 1131 | shape = (5,5) 1132 | fill = 0 1133 | position = (1,1) 1134 | 1135 | R = np.ones(shape, dtype=Z.dtype)*fill 1136 | P = np.array(list(position)).astype(int) 1137 | Rs = np.array(list(R.shape)).astype(int) 1138 | Zs = np.array(list(Z.shape)).astype(int) 1139 | 1140 | R_start = np.zeros((len(shape),)).astype(int) 1141 | R_stop = np.array(list(shape)).astype(int) 1142 | Z_start = (P-Rs//2) 1143 | Z_stop = (P+Rs//2)+Rs%2 1144 | 1145 | R_start = (R_start - np.minimum(Z_start,0)).tolist() 1146 | Z_start = (np.maximum(Z_start,0)).tolist() 1147 | R_stop = np.maximum(R_start, (R_stop - np.maximum(Z_stop-Zs,0))).tolist() 1148 | Z_stop = (np.minimum(Z_stop,Zs)).tolist() 1149 | 1150 | r = [slice(start,stop) for start,stop in zip(R_start,R_stop)] 1151 | z = [slice(start,stop) for start,stop in zip(Z_start,Z_stop)] 1152 | R[r] = Z[z] 1153 | print(Z) 1154 | print(R) 1155 | 1156 | < q81 1157 | Consider an array Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], how to generate an array R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]]? (★★★) 1158 | 1159 | < h81 1160 | hint: stride_tricks.as_strided, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0) 1161 | 1162 | < a81 1163 | # Author: Stefan van der Walt 1164 | 1165 | Z = np.arange(1,15,dtype=np.uint32) 1166 | R = stride_tricks.as_strided(Z,(11,4),(4,4)) 1167 | print(R) 1168 | 1169 | # Author: Jeff Luo (@Jeff1999) 1170 | 1171 | Z = np.arange(1, 15, dtype=np.uint32) 1172 | print(sliding_window_view(Z, window_shape=4)) 1173 | 1174 | < q82 1175 | Compute a matrix rank (★★★) 1176 | 1177 | < h82 1178 | hint: np.linalg.svd, np.linalg.matrix_rank 1179 | 1180 | < a82 1181 | # Author: Stefan van der Walt 1182 | 1183 | Z = np.random.uniform(0,1,(10,10)) 1184 | U, S, V = np.linalg.svd(Z) # Singular Value Decomposition 1185 | rank = np.sum(S > 1e-10) 1186 | print(rank) 1187 | 1188 | # alternative solution: 1189 | # Author: Jeff Luo (@Jeff1999) 1190 | 1191 | rank = np.linalg.matrix_rank(Z) 1192 | print(rank) 1193 | 1194 | < q83 1195 | How to find the most frequent value in an array? 1196 | 1197 | < h83 1198 | hint: np.bincount, argmax 1199 | 1200 | < a83 1201 | Z = np.random.randint(0,10,50) 1202 | print(np.bincount(Z).argmax()) 1203 | 1204 | < q84 1205 | Extract all the contiguous 3x3 blocks from a random 10x10 matrix (★★★) 1206 | 1207 | < h84 1208 | hint: stride_tricks.as_strided, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0) 1209 | 1210 | < a84 1211 | # Author: Chris Barker 1212 | 1213 | Z = np.random.randint(0,5,(10,10)) 1214 | n = 3 1215 | i = 1 + (Z.shape[0]-3) 1216 | j = 1 + (Z.shape[1]-3) 1217 | C = stride_tricks.as_strided(Z, shape=(i, j, n, n), strides=Z.strides + Z.strides) 1218 | print(C) 1219 | 1220 | # Author: Jeff Luo (@Jeff1999) 1221 | 1222 | Z = np.random.randint(0,5,(10,10)) 1223 | print(sliding_window_view(Z, window_shape=(3, 3))) 1224 | 1225 | < q85 1226 | Create a 2D array subclass such that Z[i,j] == Z[j,i] (★★★) 1227 | 1228 | < h85 1229 | hint: class method 1230 | 1231 | < a85 1232 | # Author: Eric O. Lebigot 1233 | # Note: only works for 2d array and value setting using indices 1234 | 1235 | class Symetric(np.ndarray): 1236 | def __setitem__(self, index, value): 1237 | i,j = index 1238 | super(Symetric, self).__setitem__((i,j), value) 1239 | super(Symetric, self).__setitem__((j,i), value) 1240 | 1241 | def symetric(Z): 1242 | return np.asarray(Z + Z.T - np.diag(Z.diagonal())).view(Symetric) 1243 | 1244 | S = symetric(np.random.randint(0,10,(5,5))) 1245 | S[2,3] = 42 1246 | print(S) 1247 | 1248 | < q86 1249 | Consider a set of p matrices with shape (n,n) and a set of p vectors with shape (n,1). How to compute the sum of of the p matrix products at once? (result has shape (n,1)) (★★★) 1250 | 1251 | < h86 1252 | hint: np.tensordot 1253 | 1254 | < a86 1255 | # Author: Stefan van der Walt 1256 | 1257 | p, n = 10, 20 1258 | M = np.ones((p,n,n)) 1259 | V = np.ones((p,n,1)) 1260 | S = np.tensordot(M, V, axes=[[0, 2], [0, 1]]) 1261 | print(S) 1262 | 1263 | # It works, because: 1264 | # M is (p,n,n) 1265 | # V is (p,n,1) 1266 | # Thus, summing over the paired axes 0 and 0 (of M and V independently), 1267 | # and 2 and 1, to remain with a (n,1) vector. 1268 | 1269 | < q87 1270 | Consider a 16x16 array, how to get the block-sum (block size is 4x4)? (★★★) 1271 | 1272 | < h87 1273 | hint: np.add.reduceat, from numpy.lib.stride_tricks import sliding_window_view (np>=1.20.0) 1274 | 1275 | < a87 1276 | # Author: Robert Kern 1277 | 1278 | Z = np.ones((16,16)) 1279 | k = 4 1280 | S = np.add.reduceat(np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0), 1281 | np.arange(0, Z.shape[1], k), axis=1) 1282 | print(S) 1283 | 1284 | # alternative solution: 1285 | # Author: Sebastian Wallkötter (@FirefoxMetzger) 1286 | 1287 | Z = np.ones((16,16)) 1288 | k = 4 1289 | 1290 | windows = np.lib.stride_tricks.sliding_window_view(Z, (k, k)) 1291 | S = windows[::k, ::k, ...].sum(axis=(-2, -1)) 1292 | 1293 | # Author: Jeff Luo (@Jeff1999) 1294 | 1295 | Z = np.ones((16, 16)) 1296 | k = 4 1297 | print(sliding_window_view(Z, window_shape=(k, k))[::k, ::k].sum(axis=(-2, -1))) 1298 | 1299 | < q88 1300 | How to implement the Game of Life using numpy arrays? (★★★) 1301 | 1302 | < h88 1303 | No hints provided... 1304 | 1305 | < a88 1306 | # Author: Nicolas Rougier 1307 | 1308 | def iterate(Z): 1309 | # Count neighbours 1310 | N = (Z[0:-2,0:-2] + Z[0:-2,1:-1] + Z[0:-2,2:] + 1311 | Z[1:-1,0:-2] + Z[1:-1,2:] + 1312 | Z[2: ,0:-2] + Z[2: ,1:-1] + Z[2: ,2:]) 1313 | 1314 | # Apply rules 1315 | birth = (N==3) & (Z[1:-1,1:-1]==0) 1316 | survive = ((N==2) | (N==3)) & (Z[1:-1,1:-1]==1) 1317 | Z[...] = 0 1318 | Z[1:-1,1:-1][birth | survive] = 1 1319 | return Z 1320 | 1321 | Z = np.random.randint(0,2,(50,50)) 1322 | for i in range(100): Z = iterate(Z) 1323 | print(Z) 1324 | 1325 | < q89 1326 | How to get the n largest values of an array (★★★) 1327 | 1328 | < h89 1329 | hint: np.argsort | np.argpartition 1330 | 1331 | < a89 1332 | Z = np.arange(10000) 1333 | np.random.shuffle(Z) 1334 | n = 5 1335 | 1336 | # Slow 1337 | print (Z[np.argsort(Z)[-n:]]) 1338 | 1339 | # Fast 1340 | print (Z[np.argpartition(-Z,n)[:n]]) 1341 | 1342 | < q90 1343 | Given an arbitrary number of vectors, build the cartesian product (every combinations of every item) (★★★) 1344 | 1345 | < h90 1346 | hint: np.indices 1347 | 1348 | < a90 1349 | # Author: Stefan Van der Walt 1350 | 1351 | def cartesian(arrays): 1352 | arrays = [np.asarray(a) for a in arrays] 1353 | shape = (len(x) for x in arrays) 1354 | 1355 | ix = np.indices(shape, dtype=int) 1356 | ix = ix.reshape(len(arrays), -1).T 1357 | 1358 | for n, arr in enumerate(arrays): 1359 | ix[:, n] = arrays[n][ix[:, n]] 1360 | 1361 | return ix 1362 | 1363 | print (cartesian(([1, 2, 3], [4, 5], [6, 7]))) 1364 | 1365 | < q91 1366 | How to create a record array from a regular array? (★★★) 1367 | 1368 | < h91 1369 | hint: np.core.records.fromarrays 1370 | 1371 | < a91 1372 | Z = np.array([("Hello", 2.5, 3), 1373 | ("World", 3.6, 2)]) 1374 | R = np.core.records.fromarrays(Z.T, 1375 | names='col1, col2, col3', 1376 | formats = 'S8, f8, i8') 1377 | print(R) 1378 | 1379 | < q92 1380 | Consider a large vector Z, compute Z to the power of 3 using 3 different methods (★★★) 1381 | 1382 | < h92 1383 | hint: np.power, *, np.einsum 1384 | 1385 | < a92 1386 | # Author: Ryan G. 1387 | 1388 | x = np.random.rand(int(5e7)) 1389 | 1390 | %timeit np.power(x,3) 1391 | %timeit x*x*x 1392 | %timeit np.einsum('i,i,i->i',x,x,x) 1393 | 1394 | < q93 1395 | Consider two arrays A and B of shape (8,3) and (2,2). How to find rows of A that contain elements of each row of B regardless of the order of the elements in B? (★★★) 1396 | 1397 | < h93 1398 | hint: np.where 1399 | 1400 | < a93 1401 | # Author: Gabe Schwartz 1402 | 1403 | A = np.random.randint(0,5,(8,3)) 1404 | B = np.random.randint(0,5,(2,2)) 1405 | 1406 | C = (A[..., np.newaxis, np.newaxis] == B) 1407 | rows = np.where(C.any((3,1)).all(1))[0] 1408 | print(rows) 1409 | 1410 | < q94 1411 | Considering a 10x3 matrix, extract rows with unequal values (e.g. [2,2,3]) (★★★) 1412 | 1413 | < h94 1414 | No hints provided... 1415 | 1416 | < a94 1417 | # Author: Robert Kern 1418 | 1419 | Z = np.random.randint(0,5,(10,3)) 1420 | print(Z) 1421 | # solution for arrays of all dtypes (including string arrays and record arrays) 1422 | E = np.all(Z[:,1:] == Z[:,:-1], axis=1) 1423 | U = Z[~E] 1424 | print(U) 1425 | # soluiton for numerical arrays only, will work for any number of columns in Z 1426 | U = Z[Z.max(axis=1) != Z.min(axis=1),:] 1427 | print(U) 1428 | 1429 | < q95 1430 | Convert a vector of ints into a matrix binary representation (★★★) 1431 | 1432 | < h95 1433 | hint: np.unpackbits 1434 | 1435 | < a95 1436 | # Author: Warren Weckesser 1437 | 1438 | I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128]) 1439 | B = ((I.reshape(-1,1) & (2**np.arange(8))) != 0).astype(int) 1440 | print(B[:,::-1]) 1441 | 1442 | # Author: Daniel T. McDonald 1443 | 1444 | I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128], dtype=np.uint8) 1445 | print(np.unpackbits(I[:, np.newaxis], axis=1)) 1446 | 1447 | < q96 1448 | Given a two dimensional array, how to extract unique rows? (★★★) 1449 | 1450 | < h96 1451 | hint: np.ascontiguousarray | np.unique 1452 | 1453 | < a96 1454 | # Author: Jaime Fernández del Río 1455 | 1456 | Z = np.random.randint(0,2,(6,3)) 1457 | T = np.ascontiguousarray(Z).view(np.dtype((np.void, Z.dtype.itemsize * Z.shape[1]))) 1458 | _, idx = np.unique(T, return_index=True) 1459 | uZ = Z[idx] 1460 | print(uZ) 1461 | 1462 | # Author: Andreas Kouzelis 1463 | # NumPy >= 1.13 1464 | uZ = np.unique(Z, axis=0) 1465 | print(uZ) 1466 | 1467 | < q97 1468 | Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function (★★★) 1469 | 1470 | < h97 1471 | hint: np.einsum 1472 | 1473 | < a97 1474 | # Author: Alex Riley 1475 | # Make sure to read: http://ajcr.net/Basic-guide-to-einsum/ 1476 | 1477 | A = np.random.uniform(0,1,10) 1478 | B = np.random.uniform(0,1,10) 1479 | 1480 | np.einsum('i->', A) # np.sum(A) 1481 | np.einsum('i,i->i', A, B) # A * B 1482 | np.einsum('i,i', A, B) # np.inner(A, B) 1483 | np.einsum('i,j->ij', A, B) # np.outer(A, B) 1484 | 1485 | < q98 1486 | Considering a path described by two vectors (X,Y), how to sample it using equidistant samples (★★★)? 1487 | 1488 | < h98 1489 | hint: np.cumsum, np.interp 1490 | 1491 | < a98 1492 | # Author: Bas Swinckels 1493 | 1494 | phi = np.arange(0, 10*np.pi, 0.1) 1495 | a = 1 1496 | x = a*phi*np.cos(phi) 1497 | y = a*phi*np.sin(phi) 1498 | 1499 | dr = (np.diff(x)**2 + np.diff(y)**2)**.5 # segment lengths 1500 | r = np.zeros_like(x) 1501 | r[1:] = np.cumsum(dr) # integrate path 1502 | r_int = np.linspace(0, r.max(), 200) # regular spaced path 1503 | x_int = np.interp(r_int, r, x) # integrate path 1504 | y_int = np.interp(r_int, r, y) 1505 | 1506 | < q99 1507 | Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n. (★★★) 1508 | 1509 | < h99 1510 | hint: np.logical_and.reduce, np.mod 1511 | 1512 | < a99 1513 | # Author: Evgeni Burovski 1514 | 1515 | X = np.asarray([[1.0, 0.0, 3.0, 8.0], 1516 | [2.0, 0.0, 1.0, 1.0], 1517 | [1.5, 2.5, 1.0, 0.0]]) 1518 | n = 4 1519 | M = np.logical_and.reduce(np.mod(X, 1) == 0, axis=-1) 1520 | M &= (X.sum(axis=-1) == n) 1521 | print(X[M]) 1522 | 1523 | < q100 1524 | Compute bootstrapped 95% confidence intervals for the mean of a 1D array X (i.e., resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means). (★★★) 1525 | 1526 | < h100 1527 | hint: np.percentile 1528 | 1529 | < a100 1530 | # Author: Jessica B. Hamrick 1531 | 1532 | X = np.random.randn(100) # random 1D array 1533 | N = 1000 # number of bootstrap samples 1534 | idx = np.random.randint(0, X.size, (N, X.size)) 1535 | means = X[idx].mean(axis=1) 1536 | confint = np.percentile(means, [2.5, 97.5]) 1537 | print(confint) 1538 | -------------------------------------------------------------------------------- /source/headers.ktx: -------------------------------------------------------------------------------- 1 | < header 2 | # 100 numpy exercises 3 | 4 | This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow 5 | and in the numpy documentation. The goal of this collection is to offer a quick reference for both old 6 | and new users but also to provide a set of exercises for those who teach. 7 | 8 | 9 | If you find an error or think you've a better way to solve some of them, feel 10 | free to open an issue at . 11 | 12 | 13 | < sub_header 14 | File automatically generated. See the documentation to update questions/answers/hints programmatically. 15 | 16 | 17 | < jupyter_instruction 18 | Run the `initialize.py` module, then for each question you can query the 19 | answer or an hint with `hint(n)` or `answer(n)` for `n` question number. 20 | 21 | 22 | < jupyter_instruction_rand 23 | Run the `initialize.py` module, then call a random question with `pick()` an hint towards its solution with 24 | `hint(n)` and the answer with `answer(n)`, where n is the number of the picked question. 25 | 26 | --------------------------------------------------------------------------------