Skip to content

Commit a2b929f

Browse files
[numpy.md] Update np.random → Generator API (#549)
1 parent 3213613 commit a2b929f

1 file changed

Lines changed: 26 additions & 23 deletions

File tree

lectures/numpy.md

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,8 @@ a
864864
Mutability leads to the following behavior (which can be shocking to MATLAB programmers...)
865865

866866
```{code-cell} python3
867-
a = np.random.randn(3)
867+
rng = np.random.default_rng()
868+
a = rng.standard_normal(3)
868869
a
869870
```
870871

@@ -894,7 +895,7 @@ It is of course possible to make `b` an independent copy of `a` when required.
894895
This can be done using `np.copy`
895896

896897
```{code-cell} python3
897-
a = np.random.randn(3)
898+
a = rng.standard_normal(3)
898899
a
899900
```
900901

@@ -972,7 +973,7 @@ def f(x):
972973
The NumPy function `np.where` provides a vectorized alternative:
973974

974975
```{code-cell} python3
975-
x = np.random.randn(4)
976+
x = rng.standard_normal(4)
976977
x
977978
```
978979

@@ -1049,11 +1050,12 @@ z[z > 3]
10491050
NumPy provides some additional functionality related to scientific programming
10501051
through its sub-packages.
10511052

1052-
We've already seen how we can generate random variables using np.random
1053+
We've already seen how we can generate random variables using NumPy's
1054+
[random `Generator`](https://numpy.org/doc/stable/reference/random/generator.html#random-generator).
10531055

10541056
```{code-cell} python3
1055-
z = np.random.randn(10000) # Generate standard normals
1056-
y = np.random.binomial(10, 0.5, size=1000) # 1,000 draws from Bin(10, 0.5)
1057+
z = rng.standard_normal(10000) # Generate standard normals
1058+
y = rng.binomial(10, 0.5, size=1000) # 1,000 draws from Bin(10, 0.5)
10571059
y.mean()
10581060
```
10591061

@@ -1099,7 +1101,7 @@ It takes a few seconds to run.
10991101
n = 20
11001102
m = 1000
11011103
for i in range(n):
1102-
X = np.random.randn(m, m)
1104+
X = rng.standard_normal((m, m))
11031105
λ = np.linalg.eigvals(X)
11041106
```
11051107

@@ -1240,28 +1242,28 @@ Here's our first pass at a solution:
12401242

12411243
```{code-cell} python3
12421244
from numpy import cumsum
1243-
from numpy.random import uniform
12441245
12451246
class DiscreteRV:
12461247
"""
12471248
Generates an array of draws from a discrete random variable with vector of
12481249
probabilities given by q.
12491250
"""
12501251
1251-
def __init__(self, q):
1252+
def __init__(self, q, seed=None):
12521253
"""
12531254
The argument q is a NumPy array, or array like, nonnegative and sums
12541255
to 1
12551256
"""
12561257
self.q = q
12571258
self.Q = cumsum(q)
1259+
self.rng = np.random.default_rng(seed)
12581260
12591261
def draw(self, k=1):
12601262
"""
12611263
Returns k draws from q. For each such draw, the value i is returned
12621264
with probability q[i].
12631265
"""
1264-
return self.Q.searchsorted(uniform(0, 1, size=k))
1266+
return self.Q.searchsorted(self.rng.uniform(0, 1, size=k))
12651267
```
12661268

12671269
The logic is not obvious, but if you take your time and read it slowly,
@@ -1390,7 +1392,8 @@ Here's an example of usage
13901392

13911393
```{code-cell} python3
13921394
fig, ax = plt.subplots()
1393-
X = np.random.randn(1000)
1395+
rng = np.random.default_rng()
1396+
X = rng.standard_normal(1000)
13941397
F = ECDF(X)
13951398
F.plot(ax)
13961399
```
@@ -1411,9 +1414,9 @@ In this exercise, try to use `for` loops to replicate the result of the followin
14111414

14121415
```{code-cell} python3
14131416
1414-
np.random.seed(123)
1415-
x = np.random.randn(4, 4)
1416-
y = np.random.randn(4)
1417+
rng = np.random.default_rng(123)
1418+
x = rng.standard_normal((4, 4))
1419+
y = rng.standard_normal(4)
14171420
A = x / y
14181421
```
14191422

@@ -1441,9 +1444,9 @@ Now we can import the quantecon package.
14411444

14421445
```{code-cell} python3
14431446
1444-
np.random.seed(123)
1445-
x = np.random.randn(1000, 100, 100)
1446-
y = np.random.randn(100)
1447+
rng = np.random.default_rng(123)
1448+
x = rng.standard_normal((1000, 100, 100))
1449+
y = rng.standard_normal(100)
14471450
14481451
with qe.Timer("Broadcasting operation"):
14491452
B = x / y
@@ -1469,9 +1472,9 @@ print(B)
14691472
**Part 1 Solution**
14701473

14711474
```{code-cell} python3
1472-
np.random.seed(123)
1473-
x = np.random.randn(4, 4)
1474-
y = np.random.randn(4)
1475+
rng = np.random.default_rng(123)
1476+
x = rng.standard_normal((4, 4))
1477+
y = rng.standard_normal(4)
14751478
14761479
C = np.empty_like(x)
14771480
n = len(x)
@@ -1500,9 +1503,9 @@ print(np.array_equal(A, C))
15001503

15011504
```{code-cell} python3
15021505
1503-
np.random.seed(123)
1504-
x = np.random.randn(1000, 100, 100)
1505-
y = np.random.randn(100)
1506+
rng = np.random.default_rng(123)
1507+
x = rng.standard_normal((1000, 100, 100))
1508+
y = rng.standard_normal(100)
15061509
15071510
with qe.Timer("For loop operation"):
15081511
D = np.empty_like(x)

0 commit comments

Comments
 (0)