From 4291cf4c1dae991d85fc6af5db696ca1d65ce2c1 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Sat, 10 Feb 2018 15:41:20 +0000
Subject: [PATCH] Fix typos, comment on savetxt(fmt=) parameter, emphasise 1D
 vectors in numpy

---
 getting_started/04_numpy.ipynb | 88 +++++++++++++++++++++++++++++-----
 getting_started/04_numpy.md    | 72 +++++++++++++++++++++++-----
 2 files changed, 138 insertions(+), 22 deletions(-)

diff --git a/getting_started/04_numpy.ipynb b/getting_started/04_numpy.ipynb
index 8c7f1d7..9ce491b 100644
--- a/getting_started/04_numpy.ipynb
+++ b/getting_started/04_numpy.ipynb
@@ -120,7 +120,7 @@
     "unwieldy when you have more than a couple of dimensions.\n",
     "\n",
     "\n",
-    "___Numy array == Matlab matrix:___ These are in contrast to the Numpy array\n",
+    "___Numpy array == Matlab matrix:___ These are in contrast to the Numpy array\n",
     "and Matlab matrix, which are both thin wrappers around a contiguous chunk of\n",
     "memory, and which provide blazing-fast performance (because behind the scenes\n",
     "in both Numpy and Matlab, it's C, C++ and FORTRAN all the way down).\n",
@@ -314,7 +314,7 @@
     "> for more information.\n",
     "\n",
     "\n",
-    "  Of course you can also save data out to a text file just as easily, with\n",
+    "Of course you can also save data out to a text file just as easily, with\n",
     "[`numpy.savetxt`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.savetxt.html):"
    ]
   },
@@ -336,6 +336,14 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
+    "> The `fmt` argument to the `numpy.savetxt` function uses a specification\n",
+    "> language similar to that used in the C `printf` function - in the example\n",
+    "> above, `'%i`' indicates that the values of the array should be output as\n",
+    "> signed integers. See the [`numpy.savetxt`\n",
+    "> documentation](https://docs.scipy.org/doc/numpy/reference/generated/numpy.savetxt.html)\n",
+    "> for more details on specifying the output format.\n",
+    "\n",
+    "\n",
     "<a class=\"anchor\" id=\"array-properties\"></a>\n",
     "### Array properties\n",
     "\n",
@@ -368,7 +376,9 @@
    "source": [
     "> As depicted above, passing a Numpy array to the built-in `len` function will\n",
     "> only give you the length of the first dimension, so you will typically want\n",
-    "> to avoid using it - use the `size` attribute instead.\n",
+    "> to avoid using it - instead, use the `size` attribute if you want to know\n",
+    "> how many elements are in an array, or the `shape` attribute if you want to\n",
+    "> know the array shape.\n",
     "\n",
     "\n",
     "<a class=\"anchor\" id=\"descriptive-statistics\"></a>\n",
@@ -402,6 +412,35 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
+    "These methods can also be applied to arrays with multiple dimensions:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "a = np.random.randint(1, 10, (3, 3))\n",
+    "print('a:')\n",
+    "print(a)\n",
+    "print('min:             ', a.min())\n",
+    "print('row mins:        ', a.min(axis=1))\n",
+    "print('col mins:        ', a.min(axis=0))\n",
+    "print('Min index      : ', a.argmin())\n",
+    "print('Row min indices: ', a.argmin(axis=1))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Note that, for a multi-dimensional array, the `argmin` and `argmax` methods\n",
+    "will return the (0-based) index of the minimum/maximum values into a\n",
+    "[flattened](https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.ndarray.flatten.html)\n",
+    "view of the array.\n",
+    "\n",
+    "\n",
     "> <sup>2</sup> Python, being an object-oriented language, distinguishes\n",
     "> between _functions_ and _methods_. Hopefully we all know what a function is\n",
     "> - a _method_ is simply the term used to refer to a function that is\n",
@@ -732,6 +771,40 @@
     "> backwards-compatibility, go ahead and use it!\n",
     "\n",
     "\n",
+    "One potential source of confusion for those of you who are used to Matlab's\n",
+    "linear algebra-based take on things is that Numpy treats row and column\n",
+    "vectors differently - you should take a break now and skim over the [appendix\n",
+    "on vectors in Numpy](#appendix-vectors-in-numpy).\n",
+    "\n",
+    "\n",
+    "For matrix-by-vector multiplications, a 1-dimensional Numpy array may be\n",
+    "treated as _either_ a row vector _or_ a column vector, depending on where\n",
+    "it is in the expression:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "a = np.arange(1, 5).reshape((2, 2))\n",
+    "b = np.random.randint(1, 10, 2)\n",
+    "\n",
+    "print('a:')\n",
+    "print(a)\n",
+    "print('b:', b)\n",
+    "\n",
+    "print('a @ b - b is a column vector:')\n",
+    "print(a @ b)\n",
+    "print('b @ a - b is a row vector:')\n",
+    "print(b @ a)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
     "<a class=\"anchor\" id=\"broadcasting\"></a>\n",
     "### Broadcasting\n",
     "\n",
@@ -778,13 +851,6 @@
     "> for that dimension.\n",
     "\n",
     "\n",
-    "Note that Numpy treats row and column vectors differently than in Matlab,\n",
-    "which is a potential source of confusion for those of you who are used to\n",
-    "Matlab's linear algebra-based take on things. You might wish to take a break\n",
-    "now to read [the appendix](#appendix-vectors-in-numpy) for a discussion on\n",
-    "vectors in Numpy.\n",
-    "\n",
-    "\n",
     "Here is a more useful example, where we use broadcasting to de-mean the rows\n",
     "or columns of an array:"
    ]
@@ -1125,7 +1191,7 @@
    "metadata": {},
    "source": [
     "The `numpy.where` function can be combined with boolean arrays to easily\n",
-    "generate of coordinate arrays for values which meet some condition:"
+    "generate coordinate arrays for values which meet some condition:"
    ]
   },
   {
diff --git a/getting_started/04_numpy.md b/getting_started/04_numpy.md
index a97a694..5cbabce 100644
--- a/getting_started/04_numpy.md
+++ b/getting_started/04_numpy.md
@@ -98,7 +98,7 @@ array in Matlab - they can store anything, but are extremely inefficient, and
 unwieldy when you have more than a couple of dimensions.
 
 
-___Numy array == Matlab matrix:___ These are in contrast to the Numpy array
+___Numpy array == Matlab matrix:___ These are in contrast to the Numpy array
 and Matlab matrix, which are both thin wrappers around a contiguous chunk of
 memory, and which provide blazing-fast performance (because behind the scenes
 in both Numpy and Matlab, it's C, C++ and FORTRAN all the way down).
@@ -236,7 +236,7 @@ print(data)
 > for more information.
 
 
-  Of course you can also save data out to a text file just as easily, with
+Of course you can also save data out to a text file just as easily, with
 [`numpy.savetxt`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.savetxt.html):
 
 
@@ -250,6 +250,13 @@ with open('mydata.txt', 'rt') as f:
 ```
 
 
+> The `fmt` argument to the `numpy.savetxt` function uses a specification
+> language similar to that used in the C `printf` function - in the example
+> above, `'%i`' indicates that the values of the array should be output as
+> signed integers. See the [`numpy.savetxt`
+> documentation](https://docs.scipy.org/doc/numpy/reference/generated/numpy.savetxt.html)
+> for more details on specifying the output format.
+
 
 <a class="anchor" id="array-properties"></a>
 ### Array properties
@@ -275,7 +282,9 @@ print('Length of first dimension: ', len(z))
 
 > As depicted above, passing a Numpy array to the built-in `len` function will
 > only give you the length of the first dimension, so you will typically want
-> to avoid using it - use the `size` attribute instead.
+> to avoid using it - instead, use the `size` attribute if you want to know
+> how many elements are in an array, or the `shape` attribute if you want to
+> know the array shape.
 
 
 <a class="anchor" id="descriptive-statistics"></a>
@@ -301,6 +310,27 @@ print('prod:         ', a.prod())
 ```
 
 
+These methods can also be applied to arrays with multiple dimensions:
+
+
+```
+a = np.random.randint(1, 10, (3, 3))
+print('a:')
+print(a)
+print('min:             ', a.min())
+print('row mins:        ', a.min(axis=1))
+print('col mins:        ', a.min(axis=0))
+print('Min index      : ', a.argmin())
+print('Row min indices: ', a.argmin(axis=1))
+```
+
+
+Note that, for a multi-dimensional array, the `argmin` and `argmax` methods
+will return the (0-based) index of the minimum/maximum values into a
+[flattened](https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.ndarray.flatten.html)
+view of the array.
+
+
 > <sup>2</sup> Python, being an object-oriented language, distinguishes
 > between _functions_ and _methods_. Hopefully we all know what a function is
 > - a _method_ is simply the term used to refer to a function that is
@@ -541,6 +571,33 @@ print(b.dot(a))
 > backwards-compatibility, go ahead and use it!
 
 
+One potential source of confusion for those of you who are used to Matlab's
+linear algebra-based take on things is that Numpy treats row and column
+vectors differently - you should take a break now and skim over the [appendix
+on vectors in Numpy](#appendix-vectors-in-numpy).
+
+
+For matrix-by-vector multiplications, a 1-dimensional Numpy array may be
+treated as _either_ a row vector _or_ a column vector, depending on where
+it is in the expression:
+
+
+```
+a = np.arange(1, 5).reshape((2, 2))
+b = np.random.randint(1, 10, 2)
+
+print('a:')
+print(a)
+print('b:', b)
+
+print('a @ b - b is a column vector:')
+print(a @ b)
+print('b @ a - b is a row vector:')
+print(b @ a)
+```
+
+
+
 <a class="anchor" id="broadcasting"></a>
 ### Broadcasting
 
@@ -579,13 +636,6 @@ print(a * b.reshape(-1, 1))
 > for that dimension.
 
 
-Note that Numpy treats row and column vectors differently than in Matlab,
-which is a potential source of confusion for those of you who are used to
-Matlab's linear algebra-based take on things. You might wish to take a break
-now to read [the appendix](#appendix-vectors-in-numpy) for a discussion on
-vectors in Numpy.
-
-
 Here is a more useful example, where we use broadcasting to de-mean the rows
 or columns of an array:
 
@@ -840,7 +890,7 @@ for r, c, v in zip(rows, cols, indexed):
 
 
 The `numpy.where` function can be combined with boolean arrays to easily
-generate of coordinate arrays for values which meet some condition:
+generate coordinate arrays for values which meet some condition:
 
 
 ```
-- 
GitLab