diff options
author | Matti Picus <matti.picus@gmail.com> | 2021-07-12 23:34:20 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-12 23:34:20 +0300 |
commit | e14d47ce9fe29884a524322b295b723cf8ee1e08 (patch) | |
tree | b1c0ea4ace6931e2d7eed50a6929a4be293eb17b | |
parent | b47c3c1c70644c84dac18de878cd53d1b103595a (diff) | |
parent | 11caec33ed4b531c7861a448d8728eafdd01a118 (diff) | |
download | numpy-e14d47ce9fe29884a524322b295b723cf8ee1e08.tar.gz |
Merge pull request #19418 from melissawm/link-tutorials
DOC: Removing tutorials from sphinx documentation
-rw-r--r-- | doc/source/user/index.rst | 2 | ||||
-rw-r--r-- | doc/source/user/quickstart.rst | 2 | ||||
-rw-r--r-- | doc/source/user/tutorial-ma.rst | 387 | ||||
-rw-r--r-- | doc/source/user/tutorial-svd.rst | 524 | ||||
-rw-r--r-- | doc/source/user/tutorials_index.rst | 16 | ||||
-rw-r--r-- | doc/source/user/who_covid_19_sit_rep_time_series.csv | 115 |
6 files changed, 2 insertions, 1044 deletions
diff --git a/doc/source/user/index.rst b/doc/source/user/index.rst index b47d6634e..9cfdfa1aa 100644 --- a/doc/source/user/index.rst +++ b/doc/source/user/index.rst @@ -21,7 +21,7 @@ details are found in :ref:`reference`. numpy-for-matlab-users building c-info - tutorials_index + NumPy Tutorials <https://numpy.org/numpy-tutorials> howtos_index depending_on_numpy diff --git a/doc/source/user/quickstart.rst b/doc/source/user/quickstart.rst index 9f3d6a040..6143b1a3d 100644 --- a/doc/source/user/quickstart.rst +++ b/doc/source/user/quickstart.rst @@ -1482,4 +1482,4 @@ Further reading - `SciPy Tutorial <https://docs.scipy.org/doc/scipy/reference/tutorial/index.html>`__ - `SciPy Lecture Notes <https://scipy-lectures.org>`__ - A `matlab, R, IDL, NumPy/SciPy dictionary <http://mathesaurus.sf.net/>`__ -- :doc:`tutorial-svd` +- `Linear algebra on n-dimensional arrays (Tutorial) <https://numpy.org/numpy-tutorials/content/tutorial-svd.html>`__ diff --git a/doc/source/user/tutorial-ma.rst b/doc/source/user/tutorial-ma.rst deleted file mode 100644 index a21c4aae1..000000000 --- a/doc/source/user/tutorial-ma.rst +++ /dev/null @@ -1,387 +0,0 @@ -======================= -Tutorial: Masked Arrays -======================= - -.. currentmodule:: numpy - -.. testsetup:: - - import numpy as np - np.random.seed(1) - -Prerequisites -------------- - -Before reading this tutorial, you should know a bit of Python. If you -would like to refresh your memory, take a look at the -:doc:`Python tutorial <python:tutorial/index>`. - -If you want to be able to run the examples in this tutorial, you should also -have `matplotlib <https://matplotlib.org/>`_ installed on your computer. - -Learner profile ---------------- - -This tutorial is for people who have a basic understanding of NumPy and want to -understand how masked arrays and the :mod:`numpy.ma` module can be used in -practice. - -Learning Objectives -------------------- - -After this tutorial, you should be able to: - -- Understand what are masked arrays and how they can be created -- Understand how to access and modify data for masked arrays -- Decide when the use of masked arrays is appropriate in some of your - applications - -What are masked arrays? ------------------------ - -Consider the following problem. You have a dataset with missing or invalid -entries. If you're doing any kind of processing on this data, and want to -`skip` or flag these unwanted entries without just deleting them, you may have -to use conditionals or filter your data somehow. The :mod:`numpy.ma` module -provides some of the same funcionality of -:class:`NumPy ndarrays <numpy.ndarray>` with added structure to ensure -invalid entries are not used in computation. - -From the :mod:`Reference Guide <numpy.ma>`: - - A masked array is the combination of a standard :class:`numpy.ndarray` and - a **mask**. A mask is either ``nomask``, indicating that no value of the - associated array is invalid, or an array of booleans that determines for - each element of the associated array whether the value is valid or not. - When an element of the mask is ``False``, the corresponding element of the - associated array is valid and is said to be unmasked. When an element of - the mask is ``True``, the corresponding element of the associated array is - said to be masked (invalid). - - -We can think of a :class:`MaskedArray <numpy.ma.MaskedArray>` as a -combination of: - -- Data, as a regular :class:`numpy.ndarray` of any shape or datatype; -- A boolean mask with the same shape as the data; -- A ``fill_value``, a value that may be used to replace the invalid entries - in order to return a standard :class:`numpy.ndarray`. - -When can they be useful? ------------------------- - -There are a few situations where masked arrays can be more useful than just -eliminating the invalid entries of an array: - -- When you want to preserve the values you masked for later processing, without - copying the array; -- When you have to handle many arrays, each with their own mask. If the mask is - part of the array, you avoid bugs and the code is possibly more compact; -- When you have different flags for missing or invalid values, and wish to - preserve these flags without replacing them in the original dataset, but - exclude them from computations; -- If you can't avoid or eliminate missing values, but don't want to deal with - :class:`NaN <numpy.nan>` (Not A Number) values in your operations. - -Masked arrays are also a good idea since the :mod:`numpy.ma` module also -comes with a specific implementation of most :term:`NumPy universal functions -(ufuncs) <ufunc>`, which means that you can still apply fast vectorized -functions and operations on masked data. The output is then a masked array. -We'll see some examples of how this works in practice below. - -Using masked arrays to see COVID-19 data ----------------------------------------- - -From `Kaggle <https://www.kaggle.com/atilamadai/covid19>`_ it is possible to -download a dataset with initial data about the COVID-19 outbreak in the -beginning of 2020. We are going to look at a small subset of this data, -contained in the file ``who_covid_19_sit_rep_time_series.csv``. - -.. ipython:: python - - import numpy as np - import os - # The os.getcwd() function returns the current folder; you can change - # the filepath variable to point to the folder where you saved the .csv file - filepath = os.getcwd() - @suppress - filepath = os.path.join(filepath, "source", "user") - filename = os.path.join(filepath, "who_covid_19_sit_rep_time_series.csv") - -The data file contains data of different types and is organized as follows: - -- The first row is a header line that (mostly) describes the data in each column - that follow in the rows below, and beginning in the fourth column, the header - is the date of the observation. -- The second through seventh row contain summary data that is of a different - type than that which we are going to examine, so we will need to exclude that - from the data with which we will work. -- The numerical data we wish to work with begins at column 4, row 8, and extends - from there to the rightmost column and the lowermost row. - -Let's explore the data inside this file for the first 14 days of records. To -gather data from the ``.csv`` file, we will use the :func:`numpy.genfromtxt` -function, making sure we select only the columns with actual numbers instead of -the first three columns which contain location data. We also skip the first 7 -rows of this file, since they contain other data we are not interested in. -Separately, we will extract the information about dates and location for this -data. - -.. ipython:: python - - # Note we are using skip_header and usecols to read only portions of the - # data file into each variable. - # Read just the dates for columns 3-7 from the first row - dates = np.genfromtxt(filename, dtype=np.unicode_, delimiter=",", - max_rows=1, usecols=range(3, 17), - encoding="utf-8-sig") - # Read the names of the geographic locations from the first two - # columns, skipping the first seven rows - locations = np.genfromtxt(filename, dtype=np.unicode_, delimiter=",", - skip_header=7, usecols=(0, 1), - encoding="utf-8-sig") - # Read the numeric data from just the first 14 days - nbcases = np.genfromtxt(filename, dtype=np.int_, delimiter=",", - skip_header=7, usecols=range(3, 17), - encoding="utf-8-sig") - -Included in the :func:`numpy.genfromtxt` function call, we have selected the -:class:`numpy.dtype` for each subset of the data (either an integer - -:class:`numpy.int_` - or a string of characters - :class:`numpy.unicode_`). We -have also used the ``encoding`` argument to select ``utf-8-sig`` as the encoding -for the file (read more about encoding in the `official Python documentation -<https://docs.python.org/3/library/codecs.html#encodings-and-unicode>`__). You -can read more about the :func:`numpy.genfromtxt` function from -the :func:`Reference Documentation <numpy.genfromtxt>` or from the -:doc:`Basic IO tutorial <basics.io.genfromtxt>`. - -Exploring the data ------------------- - -First of all, we can plot the whole set of data we have and see what it looks -like. In order to get a readable plot, we select only a few of the dates to -show in our :func:`x-axis ticks <matplotlib.pyplot.xticks>`. Note also that in -our plot command, we use ``nbcases.T`` (the transpose of the ``nbcases`` array) -since this means we will plot each row of the file as a separate line. We choose -to plot a dashed line (using the ``'--'`` line style). See the -`matplotlib <https://matplotlib.org/>`_ documentation for more info on this. - -.. ipython:: python - - import matplotlib.pyplot as plt - selected_dates = [0, 3, 11, 13] - plt.plot(dates, nbcases.T, '--'); - plt.xticks(selected_dates, dates[selected_dates]); - @savefig plot_covid_1.png - plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020"); - -.. note:: - - If you are executing the commands above in the IPython shell, it might be - necessary to use the command ``plt.show()`` to show the image window. Note - also that we use a semicolon at the end of a line to suppress its output, but - this is optional. - -The graph has a strange shape from January 24th to February 1st. It would be -interesing to know where this data comes from. If we look at the ``locations`` -array we extracted from the ``.csv`` file, we can see that we have two columns, -where the first would contain regions and the second would contain the name of -the country. However, only the first few rows contain data for the the first -column (province names in China). Following that, we only have country names. So -it would make sense to group all the data from China into a single row. For -this, we'll select from the ``nbcases`` array only the rows for which the -second entry of the ``locations`` array corresponds to China. Next, we'll use -the :func:`numpy.sum` function to sum all the selected rows (``axis=0``): - -.. ipython:: python - - china_total = nbcases[locations[:, 1] == 'China'].sum(axis=0) - china_total - -Something's wrong with this data - we are not supposed to have negative values -in a cumulative data set. What's going on? - -Missing data ------------- - -Looking at the data, here's what we find: there is a period with -**missing data**: - -.. ipython:: python - - nbcases - -All the ``-1`` values we are seeing come from :func:`numpy.genfromtxt` -attempting to read missing data from the original ``.csv`` file. Obviously, we -don't want to compute missing data as ``-1`` - we just want to skip this value -so it doesn't interfere in our analysis. After importing the :mod:`numpy.ma` -module, we'll create a new array, this time masking the invalid values: - -.. ipython:: python - - from numpy import ma - nbcases_ma = ma.masked_values(nbcases, -1) - -If we look at the ``nbcases_ma`` masked array, this is what we have: - -.. ipython:: python - - nbcases_ma - -We can see that this is a different kind of array. As mentioned in the -introduction, it has three attributes (``data``, ``mask`` and ``fill_value``). -Keep in mind that the ``mask`` attribute has a ``True`` value for elements -corresponding to **invalid** data (represented by two dashes in the ``data`` -attribute). - -.. note:: - - Adding ``-1`` to missing data is not a problem with :func:`numpy.genfromtxt`; - in this particular case, substituting the missing value with ``0`` might have - been fine, but we'll see later that this is far from a general solution. - Also, it is possible to call the :func:`numpy.genfromtxt` function using the - ``usemask`` parameter. If ``usemask=True``, :func:`numpy.genfromtxt` - automatically returns a masked array. - -Let's try and see what the data looks like excluding the first row -(data from the Hubei province in China) so we can look at the missing data more -closely: - -.. ipython:: python - - plt.plot(dates, nbcases_ma[1:].T, '--'); - plt.xticks(selected_dates, dates[selected_dates]); - @savefig plot_covid_2.png - plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020"); - -Now that our data has been masked, let's try summing up all the cases in China: - -.. ipython:: python - - china_masked = nbcases_ma[locations[:, 1] == 'China'].sum(axis=0) - china_masked - -Note that ``china_masked`` is a masked array, so it has a different data -structure than a regular NumPy array. Now, we can access its data directly by -using the ``.data`` attribute: - -.. ipython:: python - - china_total = china_masked.data - china_total - -That is better: no more negative values. However, we can still see that for some -days, the cumulative number of cases seems to go down (from 835 to 10, for -example), which does not agree with the definition of "cumulative data". If we -look more closely at the data, we can see that in the period where there was -missing data in mainland China, there was valid data for Hong Kong, Taiwan, -Macau and "Unspecified" regions of China. Maybe we can remove those from the -total sum of cases in China, to get a better understanding of the data. - -First, we'll identify the indices of locations in mainland China: - -.. ipython:: python - - china_mask = ((locations[:, 1] == 'China') & - (locations[:, 0] != 'Hong Kong') & - (locations[:, 0] != 'Taiwan') & - (locations[:, 0] != 'Macau') & - (locations[:, 0] != 'Unspecified*')) - -Now, ``china_mask`` is an array of boolean values (``True`` or ``False``); we -can check that the indices are what we wanted with the :func:`ma.nonzero` method -for masked arrays: - -.. ipython:: python - - china_mask.nonzero() - -Now we can correctly sum entries for mainland China: - -.. ipython:: python - - china_total = nbcases_ma[china_mask].sum(axis=0) - china_total - -We can replace the data with this information and plot a new graph, focusing on -Mainland China: - -.. ipython:: python - - plt.plot(dates, china_total.T, '--'); - plt.xticks(selected_dates, dates[selected_dates]); - @savefig plot_covid_3.png - plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020 - Mainland China"); - -It's clear that masked arrays are the right solution here. We cannot represent -the missing data without mischaracterizing the evolution of the curve. - -Fitting Data ------------- - -One possibility we can think of is to interpolate the missing data to estimate -the number of cases in late January. Observe that we can select the masked -elements using the ``.mask`` attribute: - -.. ipython:: python - - china_total.mask - invalid = china_total[china_total.mask] - invalid - -We can also access the valid entries by using the logical negation for this -mask: - -.. ipython:: python - - valid = china_total[~china_total.mask] - valid - -Now, if we want to create a very simple approximation for this data, we should -take into account the valid entries around the invalid ones. So first let's -select the dates for which the data is valid. Note that we can use the mask -from the ``china_total`` masked array to index the dates array: - -.. ipython:: python - - dates[~china_total.mask] - -Finally, we can use the :func:`numpy.polyfit` and :func:`numpy.polyval` -functions to create a cubic polynomial that fits the data as best as possible: - -.. ipython:: python - - t = np.arange(len(china_total)) - params = np.polyfit(t[~china_total.mask], valid, 3) - cubic_fit = np.polyval(params, t) - plt.plot(t, china_total); - @savefig plot_covid_4.png - plt.plot(t, cubic_fit, '--'); - -This plot is not so readable since the lines seem to be over each other, so -let's summarize in a more elaborate plot. We'll plot the real data when -available, and show the cubic fit for unavailable data, using this fit to -compute an estimate to the observed number of cases on January 28th 2020, 7 days -after the beginning of the records: - -.. ipython:: python - - plt.plot(t, china_total, label='Mainland China'); - plt.plot(t[china_total.mask], cubic_fit[china_total.mask], '--', - color='orange', label='Cubic estimate'); - plt.plot(7, np.polyval(params, 7), 'r*', label='7 days after start'); - plt.xticks([0, 7, 13], dates[[0, 7, 13]]); - plt.yticks([0, np.polyval(params, 7), 10000, 17500]); - plt.legend(); - @savefig plot_covid_5.png - plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020 - Mainland China\n" - "Cubic estimate for 7 days after start"); - -More reading ------------- - -Topics not covered in this tutorial can be found in the documentation: - -- :func:`Hardmasks <numpy.ma.harden_mask>` vs. :func:`softmasks - <numpy.ma.soften_mask>` -- :ref:`The numpy.ma module <maskedarray.generic>` diff --git a/doc/source/user/tutorial-svd.rst b/doc/source/user/tutorial-svd.rst deleted file mode 100644 index 7b905e51e..000000000 --- a/doc/source/user/tutorial-svd.rst +++ /dev/null @@ -1,524 +0,0 @@ -================================================ -Tutorial: Linear algebra on n-dimensional arrays -================================================ - -.. currentmodule:: numpy - -.. testsetup:: - - import numpy as np - np.random.seed(1) - -Prerequisites -------------- - -Before reading this tutorial, you should know a bit of Python. If you -would like to refresh your memory, take a look at the -:doc:`Python tutorial <python:tutorial/index>`. - -If you want to be able to run the examples in this tutorial, you should also -have `matplotlib <https://matplotlib.org/>`_ and `SciPy <https://scipy.org>`_ -installed on your computer. - -Learner profile ---------------- - -This tutorial is for people who have a basic understanding of linear -algebra and arrays in NumPy and want to understand how n-dimensional -(:math:`n>=2`) arrays are represented and can be manipulated. In particular, if -you don't know how to apply common functions to n-dimensional arrays (without -using for-loops), or if you want to understand axis and shape properties for -n-dimensional arrays, this tutorial might be of help. - -Learning Objectives -------------------- - -After this tutorial, you should be able to: - -- Understand the difference between one-, two- and n-dimensional arrays in - NumPy; -- Understand how to apply some linear algebra operations to n-dimensional - arrays without using for-loops; -- Understand axis and shape properties for n-dimensional arrays. - -Content -------- - -In this tutorial, we will use a `matrix decomposition -<https://en.wikipedia.org/wiki/Matrix_decomposition>`_ from linear algebra, the -Singular Value Decomposition, to generate a compressed approximation of an -image. We'll use the ``face`` image from the `scipy.misc` module: - - >>> from scipy import misc - >>> img = misc.face() - -.. note:: - - If you prefer, you can use your own image as you work through this tutorial. - In order to transform your image into a NumPy array that can be manipulated, - you can use the ``imread`` function from the `matplotlib.pyplot` submodule. - Alternatively, you can use the :func:`imageio.imread` function from the - ``imageio`` library. Be aware that if you use your own image, you'll likely - need to adapt the steps below. For more information on how images are treated - when converted to NumPy arrays, see :std:doc:`user_guide/numpy_images` from - the ``scikit-image`` documentation. - -Now, ``img`` is a NumPy array, as we can see when using the ``type`` function:: - - >>> type(img) - <class 'numpy.ndarray'> - -We can see the image using the `matplotlib.pyplot.imshow` function:: - - >>> import matplotlib.pyplot as plt - >>> plt.imshow(img) - -.. plot:: user/plot_face.py - :align: center - :include-source: 0 - -.. note:: - - If you are executing the commands above in the IPython shell, it might be - necessary to use the command ``plt.show()`` to show the image window. - -Shape, axis and array properties --------------------------------- - -Note that, in linear algebra, the dimension of a vector refers to the number of -entries in an array. In NumPy, it instead defines the number of axes. For -example, a 1D array is a vector such as ``[1, 2, 3]``, a 2D array is a matrix, -and so forth. - -First, let's check for the shape of the data in our array. Since this image is -two-dimensional (the pixels in the image form a rectangle), we might expect a -two-dimensional array to represent it (a matrix). However, using the ``shape`` -property of this NumPy array gives us a different result:: - - >>> img.shape - (768, 1024, 3) - -The output is a :ref:`tuple <python:tut-tuples>` with three elements, which means -that this is a three-dimensional array. In fact, since this is a color image, and -we have used the ``imread`` function to read it, the data is organized in three 2D -arrays, representing color channels (in this case, red, green and blue - RGB). You -can see this by looking at the shape above: it indicates that we have an array of -3 matrices, each having shape 768x1024. - -Furthermore, using the ``ndim`` property of this array, we can see that - -:: - - >>> img.ndim - 3 - -NumPy refers to each dimension as an `axis`. Because of how ``imread`` -works, the *first index in the 3rd axis* is the red pixel data for our image. We -can access this by using the syntax - -:: - - >>> img[:, :, 0] - array([[121, 138, 153, ..., 119, 131, 139], - [ 89, 110, 130, ..., 118, 134, 146], - [ 73, 94, 115, ..., 117, 133, 144], - ..., - [ 87, 94, 107, ..., 120, 119, 119], - [ 85, 95, 112, ..., 121, 120, 120], - [ 85, 97, 111, ..., 120, 119, 118]], dtype=uint8) - -From the output above, we can see that every value in ``img[:,:,0]`` is an -integer value between 0 and 255, representing the level of red in each -corresponding image pixel (keep in mind that this might be different if you -use your own image instead of `scipy.misc.face`). - -As expected, this is a 768x1024 matrix:: - - >>> img[:, :, 0].shape - (768, 1024) - -Since we are going to perform linear algebra operations on this data, it might -be more interesting to have real numbers between 0 and 1 in each entry of the -matrices to represent the RGB values. We can do that by setting - - >>> img_array = img / 255 - -This operation, dividing an array by a scalar, works because of NumPy's -:ref:`broadcasting rules <array-broadcasting-in-numpy>`). (Note that in -real-world applications, it would be better to use, for example, the -:func:`img_as_float <skimage.img_as_float>` utility function from -``scikit-image``). - -You can check that the above works by doing some tests; for example, inquiring -about maximum and minimum values for this array:: - - >>> img_array.max(), img_array.min() - (1.0, 0.0) - -or checking the type of data in the array:: - - >>> img_array.dtype - dtype('float64') - -Note that we can assign each color channel to a separate matrix using the slice -syntax:: - - >>> red_array = img_array[:, :, 0] - >>> green_array = img_array[:, :, 1] - >>> blue_array = img_array[:, :, 2] - -Operations on an axis ---------------------- - -It is possible to use methods from linear algebra to approximate an existing set -of data. Here, we will use the `SVD (Singular Value Decomposition) -<https://en.wikipedia.org/wiki/Singular_value_decomposition>`_ to try to rebuild -an image that uses less singular value information than the original one, while -still retaining some of its features. - -.. note:: - - We will use NumPy's linear algebra module, `numpy.linalg`, to - perform the operations in this tutorial. Most of the linear algebra - functions in this module can also be found in `scipy.linalg`, and - users are encouraged to use the `scipy` module for real-world - applications. However, it is currently not possible to apply linear - algebra operations to n-dimensional arrays using the `scipy.linalg` - module. For more information on this, check the - :doc:`scipy.linalg Reference<scipy:tutorial/linalg>`. - -To proceed, import the linear algebra submodule from NumPy:: - - >>> from numpy import linalg - -In order to extract information from a given matrix, we can use the SVD to obtain -3 arrays which can be multiplied to obtain the original matrix. From the theory -of linear algebra, given a matrix :math:`A`, the following product can be -computed: - -.. math:: - - U \Sigma V^T = A - -where :math:`U` and :math:`V^T` are square and :math:`\Sigma` is the same size -as :math:`A`. :math:`\Sigma` is a diagonal matrix and contains the -`singular values <https://en.wikipedia.org/wiki/Singular_value>`_ of :math:`A`, -organized from largest to smallest. These values are always non-negative and can -be used as an indicator of the "importance" of some features represented by the -matrix :math:`A`. - -Let's see how this works in practice with just one matrix first. Note that -according to `colorimetry <https://en.wikipedia.org/wiki/Grayscale#Colorimetric_(perceptual_luminance-preserving)_conversion_to_grayscale>`_, -it is possible to obtain a fairly reasonable grayscale version of our color -image if we apply the formula - -.. math:: - - Y = 0.2126 R + 0.7152 G + 0.0722 B - -where :math:`Y` is the array representing the grayscale image, and :math:`R, G` -and :math:`B` are the red, green and blue channel arrays we had originally. -Notice we can use the ``@`` operator (the matrix multiplication operator for -NumPy arrays, see `numpy.matmul`) for this: - -:: - - >>> img_gray = img_array @ [0.2126, 0.7152, 0.0722] - -Now, ``img_gray`` has shape - -:: - - >>> img_gray.shape - (768, 1024) - -To see if this makes sense in our image, we should use a colormap from -``matplotlib`` corresponding to the color we wish to see in out image -(otherwise, ``matplotlib`` will default to a colormap that does not -correspond to the real data). - -In our case, we are approximating the grayscale portion of the image, so we -will use the colormap ``gray``:: - - >>> plt.imshow(img_gray, cmap="gray") - -.. plot:: user/plot_gray.py - :align: center - :include-source: 0 - -Now, applying the `linalg.svd` function to this matrix, we obtain the -following decomposition: -:: - - >>> U, s, Vt = linalg.svd(img_gray) - -.. note:: - - If you are using your own image, this command might take a while to run, - depending on the size of your image and your hardware. Don't worry, this - is normal! The SVD can be a pretty intensive computation. - -Let's check that this is what we expected:: - - >>> U.shape, s.shape, Vt.shape - ((768, 768), (768,), (1024, 1024)) - -Note that ``s`` has a particular shape: it has only one dimension. This -means that some linear algebra functions that expect 2d arrays might not work. -For example, from the theory, one might expect ``s`` and ``Vt`` to be -compatible for multiplication. However, this is not true as ``s`` does not -have a second axis. Executing - -:: - - >>> s @ Vt - Traceback (most recent call last): - ... - ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, - with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 1024 is different from - 768) - -results in a ``ValueError``. This happens because having a one-dimensional -array for ``s``, in this case, is much more economic in practice than building a -diagonal matrix with the same data. To reconstruct the original matrix, we can -rebuild the diagonal matrix :math:`\Sigma` with the elements of ``s`` in its -diagonal and with the appropriate dimensions for multiplying: in our case, -:math:`\Sigma` should be 768x1024 since ``U`` is 768x768 and ``Vt`` is -1024x1024. - -:: - - >>> import numpy as np - >>> Sigma = np.zeros((768, 1024)) - >>> for i in range(768): - ... Sigma[i, i] = s[i] - -Now, we want to check if the reconstructed ``U @ Sigma @ Vt`` is -close to the original ``img_gray`` matrix. - -Approximation -------------- - -The `linalg` module includes a ``norm`` function, which -computes the norm of a vector or matrix represented in a NumPy array. For -example, from the SVD explanation above, we would expect the norm of the -difference between ``img_gray`` and the reconstructed SVD product to be small. -As expected, you should see something like - -:: - - >>> linalg.norm(img_gray - U @ Sigma @ Vt) - 1.3926466851808837e-12 - -(The actual result of this operation might be different depending on your -architecture and linear algebra setup. Regardless, you should see a small -number.) - -We could also have used the `numpy.allclose` function to make sure the -reconstructed product is, in fact, *close* to our original matrix (the -difference between the two arrays is small):: - - >>> np.allclose(img_gray, U @ Sigma @ Vt) - True - -To see if an approximation is reasonable, we can check the values in ``s``:: - - >>> plt.plot(s) - -.. plot:: user/plot_gray_svd.py - :align: center - :include-source: 0 - -In the graph, we can see that although we have 768 singular values in -``s``, most of those (after the 150th entry or so) are pretty small. So it -might make sense to use only the information related to the first (say, 50) -*singular values* to build a more economical approximation to our image. - -The idea is to consider all but the first ``k`` singular values in -``Sigma`` (which are the same as in ``s``) as zeros, keeping -``U`` and ``Vt`` intact, and computing the product of these matrices -as the approximation. - -For example, if we choose - -:: - - >>> k = 10 - -we can build the approximation by doing - -:: - - >>> approx = U @ Sigma[:, :k] @ Vt[:k, :] - -Note that we had to use only the first ``k`` rows of ``Vt``, since all -other rows would be multiplied by the zeros corresponding to the singular -values we eliminated from this approximation. - -:: - - >>> plt.imshow(approx, cmap="gray") - -.. plot:: user/plot_approx.py - :align: center - :include-source: 0 - -Now, you can go ahead and repeat this experiment with other values of `k`, and -each of your experiments should give you a slightly better (or worse) image -depending on the value you choose. - -Applying to all colors ----------------------- - -Now we want to do the same kind of operation, but to all three colors. Our -first instinct might be to repeat the same operation we did above to each color -matrix individually. However, NumPy's `broadcasting` takes care of this -for us. - -If our array has more than two dimensions, then the SVD can be applied to all -axes at once. However, the linear algebra functions in NumPy expect to see an -array of the form ``(N, M, M)``, where the first axis represents the number -of matrices. - -In our case, - -:: - - >>> img_array.shape - (768, 1024, 3) - -so we need to permutate the axis on this array to get a shape like -``(3, 768, 1024)``. Fortunately, the `numpy.transpose` function can do that for -us: - -:: - - np.transpose(x, axes=(i, j, k)) - -indicates that the axis will be reordered such that the final shape of the -transposed array will be reordered according to the indices ``(i, j, k)``. - -Let's see how this goes for our array:: - - >>> img_array_transposed = np.transpose(img_array, (2, 0, 1)) - >>> img_array_transposed.shape - (3, 768, 1024) - -Now we are ready to apply the SVD:: - - >>> U, s, Vt = linalg.svd(img_array_transposed) - -Finally, to obtain the full approximated image, we need to reassemble these -matrices into the approximation. Now, note that - -:: - - >>> U.shape, s.shape, Vt.shape - ((3, 768, 768), (3, 768), (3, 1024, 1024)) - -To build the final approximation matrix, we must understand how multiplication -across different axes works. - -Products with n-dimensional arrays ----------------------------------- - -If you have worked before with only one- or two-dimensional arrays in NumPy, -you might use `numpy.dot` and `numpy.matmul` (or the ``@`` operator) -interchangeably. However, for n-dimensional arrays, they work in very different -ways. For more details, check the documentation `numpy.matmul`. - -Now, to build our approximation, we first need to make sure that our singular -values are ready for multiplication, so we build our ``Sigma`` matrix similarly -to what we did before. The ``Sigma`` array must have dimensions -``(3, 768, 1024)``. In order to add the singular values to the diagonal of -``Sigma``, we will use the `numpy.fill_diagonal` function from NumPy, using each of -the 3 rows in ``s`` as the diagonal for each of the 3 matrices in ``Sigma``: - -:: - - >>> Sigma = np.zeros((3, 768, 1024)) - >>> for j in range(3): - ... np.fill_diagonal(Sigma[j, :, :], s[j, :]) - -Now, if we wish to rebuild the full SVD (with no approximation), we can do - -:: - - >>> reconstructed = U @ Sigma @ Vt - -Note that - -:: - - >>> reconstructed.shape - (3, 768, 1024) - -and - -:: - - >>> plt.imshow(np.transpose(reconstructed, (1, 2, 0))) - -.. plot:: user/plot_reconstructed.py - :align: center - :include-source: 0 - -should give you an image indistinguishable from the original one (although we -may introduce floating point errors for this reconstruction). In fact, -you might see a warning message saying `"Clipping input data to the -valid range for imshow with RGB data ([0..1] for floats or [0..255] for -integers)."` This is expected from the manipulation we just did on the original -image. - -Now, to do the approximation, we must choose only the first ``k`` singular -values for each color channel. This can be done using the following syntax:: - - >>> approx_img = U @ Sigma[..., :k] @ Vt[..., :k, :] - -You can see that we have selected only the first ``k`` components of the last -axis for ``Sigma`` (this means that we have used only the first ``k`` columns -of each of the three matrices in the stack), and that we have selected only the -first ``k`` components in the second-to-last axis of ``Vt`` (this means we have -selected only the first ``k`` rows from every matrix in the stack ``Vt`` and -all columns). If you are unfamiliar with the ellipsis syntax, it is a -placeholder for other axes. For more details, see the documentation on -:ref:`Indexing <basics.indexing>`. - -Now, - -:: - - >>> approx_img.shape - (3, 768, 1024) - -which is not the right shape for showing the image. Finally, reordering the axes -back to our original shape of ``(768, 1024, 3)``, we can see our approximation:: - - >>> plt.imshow(np.transpose(approx_img, (1, 2, 0))) - -.. plot:: user/plot_final.py - :align: center - :include-source: 0 - -Even though the image is not as sharp, using a small number of ``k`` singular -values (compared to the original set of 768 values), we can recover many of the -distinguishing features from this image. - -Final words ------------ - -Of course, this is not the best method to *approximate* an image. -However, there is, in fact, a result in linear algebra that says that the -approximation we built above is the best we can get to the original matrix in -terms of the norm of the difference. For more information, see *G. H. Golub and -C. F. Van Loan, Matrix Computations, Baltimore, MD, Johns Hopkins University -Press, 1985*. - -Further reading ---------------- - -- :doc:`Python tutorial <python:tutorial/index>` -- :ref:`reference` -- :doc:`SciPy Tutorial <scipy:tutorial/index>` -- `SciPy Lecture Notes <https://scipy-lectures.org>`__ -- `A matlab, R, IDL, NumPy/SciPy dictionary <http://mathesaurus.sf.net/>`__ diff --git a/doc/source/user/tutorials_index.rst b/doc/source/user/tutorials_index.rst deleted file mode 100644 index 20e2c256c..000000000 --- a/doc/source/user/tutorials_index.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _tutorials: - -################ -NumPy Tutorials -################ - -These documents are intended as an introductory overview of NumPy and its -features. For detailed reference documentation of the functions and -classes contained in the package, see the :ref:`API reference <reference>`. - -.. toctree:: - :maxdepth: 1 - - tutorial-svd - tutorial-ma - diff --git a/doc/source/user/who_covid_19_sit_rep_time_series.csv b/doc/source/user/who_covid_19_sit_rep_time_series.csv deleted file mode 100644 index 8ad5c2c23..000000000 --- a/doc/source/user/who_covid_19_sit_rep_time_series.csv +++ /dev/null @@ -1,115 +0,0 @@ -Province/States,Country/Region,WHO region,1/21/20,1/22/20,1/23/20,1/24/20,1/25/20,1/26/20,1/27/20,1/28/20,1/29/20,1/30/20,1/31/20,2/1/20,2/2/20,2/3/20,2/4/20,2/5/20,2/6/20,2/7/20,2/8/20,2/9/20,2/10/20,2/11/20,2/12/20,2/13/20,2/14/20,2/15/20,2/16/20,2/17/20,2/18/20,2/19/20,2/20/20,2/21/20,2/22/20,2/23/20,2/24/20,2/25/20,2/26/20,2/27/20,2/28/20,2/29/20,3/1/20,3/2/20,3/3/20 -Confirmed,Globally,,282,314,581,846,1320,2014,2798,4593,6065,7818,9826,11953,14557,17391,20630,24554,28276,31481,34886,37558,40554,43103,45171,46997,49053,50580,51857,71429,73332,75204,75748,76769,77794,78811,79331,80239,81109,82294,83652,85403,87137,88948,90870 -Confirmed,Mainland China,Western Pacific Region,278,309,571,830,1297,1985,2741,4537,5997,7736,9720,11821,14411,17238,20471,24363,28060,31211,34598,37251,40235,42708,44730,46550,48548,50054,51174,70635,72528,74280,74675,75569,76392,77042,77262,77780,78191,78630,78961,79394,79968,80174,80304 -Confirmed,Outside of China,,4,5,10,16,23,29,57,56,68,82,106,132,146,153,159,191,216,270,288,307,319,395,441,447,505,526,683,794,804,924,1073,1200,1402,1769,2069,2459,2918,3664,4691,6009,7169,8774,10566 -Suspected,Mainland China,Western Pacific Region,,,,,,,5794,6973,9239,12167,15238,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -Severe,Mainland China,Western Pacific Region,,,,,,,461,976,1239,1370,1527,1795,2110,2296,2788,3219,3859,4821,6101,6188,6484,7333,8204,,,,,,,,,,,,,,,,,,,, -Deaths,Mainland China,Western Pacific Region,,,,,,,80,106,132,170,213,259,304,361,425,491,564,637,723,812,909,1017,1114,1260,1381,1524,1666,1772,1870,2006,2121,2239,2348,2445,2595,2666,2718,2747,2791,2838,2873,2915,2946 -Hubei ,China,Western Pacific Region,258,270,375,375,,,,,,,,7153,9074,11177,13522,16678,19665,22112,24953,27100,29631,31728,33366,34874,51968,54406,56249,58182,59989,61682,62031,62662,63454,64084,64287,64786,65187,65596,65914,66337,66907,67103,67217 -Guangdong,China,Western Pacific Region,14,17,26,32,,,,,,,,520,604,683,797,870,944,1018,1075,1120,1151,1177,1219,1241,1261,1295,1316,1322,1328,1331,1332,1333,1339,1342,1345,1347,1347,1347,1348,1349,1349,1350,1350 -Henan,China,Western Pacific Region,,1,1,1,,,,,,,,422,493,566,675,764,851,914,981,1033,1073,1105,1135,1169,1184,1212,1231,1246,1257,1262,1265,1267,1270,1271,1271,1271,1271,1272,1272,1272,1272,1272,1272 -Zhejiang,China,Western Pacific Region,,5,5,5,,,,,,,,599,661,724,829,895,954,1006,1048,1075,1104,1117,1131,1145,1155,1162,1167,1171,1172,1173,1175,1203,1205,1205,1205,1205,1205,1205,1205,1205,1205,1206,1213 -Hunan,China,Western Pacific Region,,1,1,1,,,,,,,,389,463,521,593,661,711,772,803,838,879,912,946,968,988,1001,1004,1006,1007,1008,1010,1011,1013,1016,1016,1016,1016,1017,1017,1018,1018,1018,1018 -Anhui,China,Western Pacific Region,,,,,,,,,,,,297,340,408,480,530,591,665,733,779,830,860,889,910,934,950,962,973,982,986,987,988,989,989,989,989,989,989,990,990,990,990,990 -Jiangxi,China,Western Pacific Region,,1,2,2,,,,,,,,286,333,391,476,548,600,661,698,740,771,804,844,872,900,913,925,930,933,934,934,934,934,934,934,934,934,934,935,935,935,935,935 -Shandong,China,Western Pacific Region,,1,1,1,,,,,,,,202,225,246,270,298,343,379,407,435,459,486,497,506,519,530,537,541,543,544,546,748,750,754,755,755,756,756,756,756,756,758,758 -Jiangsu,China,Western Pacific Region,,,,,,,,,,,,202,231,271,308,341,373,408,439,468,492,515,543,570,593,604,617,626,629,631,631,631,631,631,631,631,631,631,631,631,631,631,631 -Chongqing,China,Western Pacific Region,,1,5,5,,,,,,,,238,262,300,337,366,389,411,426,446,468,486,505,518,529,537,544,551,553,555,560,567,572,573,575,576,576,576,576,576,576,576,576 -Sichuan,China,Western Pacific Region,,1,2,2,,,,,,,,207,236,254,282,301,321,344,363,386,405,417,436,451,463,470,481,495,508,514,520,525,526,526,527,529,531,534,538,538,538,538,538 -Heilongjiang,China,Western Pacific Region,,,,,,,,,,,,80,95,118,155,190,227,277,282,307,331,360,378,395,418,425,445,457,464,470,476,479,479,480,480,480,480,480,480,480,480,480,480 -Beijing,China,Western Pacific Region,5,5,10,10,,,,,,,,156,183,212,228,253,274,297,315,326,337,342,352,366,372,375,380,381,387,393,395,396,399,399,399,400,400,410,410,411,413,414,414 -Shanghai,China,Western Pacific Region,1,2,9,9,,,,,,,,153,177,193,208,233,254,269,281,292,295,302,306,313,318,326,328,331,333,333,333,334,334,335,335,335,336,337,337,337,337,337,338 -Hebei,China,Western Pacific Region,,,,,,,,,,,,96,104,113,126,135,157,171,195,206,218,239,251,265,283,291,300,301,302,306,307,308,309,311,311,311,312,317,318,318,318,318,318 -Fujian,China,Western Pacific Region,,,,,,,,,,,,144,159,179,194,205,215,224,239,250,261,267,272,279,281,285,287,290,292,293,293,293,293,293,293,294,294,296,296,296,296,296,296 -Guangxi,China,Western Pacific Region,,,,,,,,,,,,100,111,127,139,150,168,172,183,195,210,215,222,222,226,235,237,238,242,244,245,246,249,249,251,252,252,252,252,252,252,252,252 -Shaanxi,China,Western Pacific Region,,,,,,,,,,,,101,116,128,142,165,173,184,195,208,213,219,225,229,230,232,236,240,240,242,245,245,245,245,245,245,245,245,245,245,245,245,245 -Yunnan,China,Western Pacific Region,,1,1,1,,,,,,,,91,99,109,117,122,128,135,138,140,141,149,154,155,162,168,169,171,172,172,172,174,174,174,174,174,174,174,174,174,174,174,174 -Hainan,China,Western Pacific Region,,,,,,,,,,,,57,63,70,79,89,100,111,123,128,136,142,145,157,157,162,162,162,163,163,168,168,168,168,168,168,168,168,168,168,168,168,168 -Guizhou,China,Western Pacific Region,,,,,,,,,,,,29,38,46,56,64,69,77,89,96,109,118,131,135,140,143,144,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146 -Tianjin,China,Western Pacific Region,,2,2,2,,,,,,,,34,40,49,63,67,70,94,81,88,91,96,106,112,119,120,122,124,125,128,130,131,133,135,135,135,135,135,136,136,136,136,136 -Shanxi,China,Western Pacific Region,,,,,,,,,,,,47,56,66,74,81,90,96,104,115,119,122,124,126,126,127,128,129,130,131,131,132,132,132,132,133,133,133,133,133,133,133,133 -Liaoning,China,Western Pacific Region,,,,,,,,,,,,60,64,70,74,81,89,94,99,105,107,108,111,116,117,119,120,121,121,121,121,121,121,121,121,121,121,121,121,121,122,122,125 -Hong Kong,China,Western Pacific Region,,,1,2,5,5,8,8,8,10,12,13,14,15,15,18,21,24,26,26,36,42,49,50,53,56,56,57,60,62,65,68,68,70,74,81,85,91,93,94,95,98,101 -Jilin,China,Western Pacific Region,,,,,,,,,,,,17,21,31,42,54,59,65,69,78,80,81,83,84,86,88,88,89,89,90,91,91,91,91,93,93,93,93,93,93,93,93,93 -Gansu,China,Western Pacific Region,,,,,,,,,,,,35,45,51,56,57,62,70,71,81,85,86,86,87,90,90,90,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91 -Xinjiang,China,Western Pacific Region,,,,,,,,,,,,18,23,24,29,32,36,39,42,45,49,55,59,63,65,70,71,73,76,76,76,76,76,75,76,76,76,76,76,76,76,76,76 -Inner Mongolia,China,Western Pacific Region,,,,,,,,,,,,23,26,33,37,42,46,49,50,54,58,58,60,61,63,68,70,72,73,75,75,75,75,75,75,75,75,75,75,75,75,75,75 -Ningxia,China,Western Pacific Region,,,,,,,,,,,,26,28,31,34,34,40,43,45,45,49,53,58,64,67,70,70,70,70,71,71,71,71,71,71,71,71,72,72,73,73,74,74 -Taiwan,China,Western Pacific Region,,1,1,1,3,3,4,7,8,8,9,10,10,10,10,11,11,16,16,17,18,18,18,18,18,18,18,20,22,23,24,26,26,23,28,31,32,32,34,39,39,40,42 -Qinghai,China,Western Pacific Region,,,,,,,,,,,,8,9,13,15,17,18,18,18,18,18,18,18,18,18,18,18,18,18,12,18,18,18,18,18,18,18,18,18,18,18,18,18 -Macau,China,Western Pacific Region,,,1,2,2,2,5,7,7,7,7,7,7,8,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10 -Xizang,China,Western Pacific Region,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -Unspecified*,China,Western Pacific Region,,,131,384,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,Japan,Western Pacific Region,1,1,1,1,3,3,4,6,7,11,14,17,20,20,20,33,25,25,25,26,26,26,28,29,33,41,53,59,65,73,85,93,105,132,144,157,164,186,210,230,239,254,268 -,Republic of Korea,Western Pacific Region,1,1,1,2,2,2,4,4,4,4,11,12,15,15,16,18,23,24,24,27,27,28,28,28,28,28,29,30,31,51,104,204,346,602,763,977,1261,1766,2337,3150,3736,4212,4812 -,Thailand,South-East Asia Region,2,2,2,4,4,5,5,14,14,14,14,19,19,19,19,25,25,25,32,32,32,33,33,33,33,34,34,35,35,35,35,35,35,35,35,37,40,40,40,42,42,42,43 -,United States of America,Region of the Americas,,,1,1,2,2,5,5,5,5,6,7,8,11,11,11,12,12,12,12,12,13,13,14,15,15,15,15,15,15,15,15,35,35,35,53,53,59,59,62,62,62,64 -,Vietnam,Western Pacific Region,,,,2,2,2,2,2,2,2,5,6,7,8,9,10,10,12,13,14,14,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 -,Singapore,Western Pacific Region,,,,1,3,3,4,7,7,10,13,16,18,18,18,24,28,30,33,40,43,45,47,50,58,67,72,75,77,81,84,85,86,89,89,90,91,93,96,98,102,106,108 -,Italy,European Region,,,,,,,,,,,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,9,76,124,229,322,400,650,888,1128,1689,2036 -,Nepal,South-East Asia Region,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -,Australia,Western Pacific Region,,,,,3,3,4,5,7,7,9,12,12,12,12,13,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,21,21,21,22,23,23,23,24,25,27,33 -,Malaysia,Western Pacific Region,,,,,,3,4,4,4,7,8,8,8,8,10,10,12,14,15,17,18,18,18,18,19,21,22,22,22,22,22,22,22,22,22,22,22,22,24,24,24,24,29 -,Canada,Region of the Americas,,,,,,,1,2,3,3,3,4,4,4,4,5,5,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,9,9,10,10,11,11,14,19,19,27 -,Cambodia,Western Pacific Region,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -,France,European Region,,,,,3,3,3,3,4,5,6,6,6,6,6,6,6,6,6,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,18,38,57,100,100,191 -,Sri Lanka,South-East Asia Region,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -,Iran,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,5,18,28,43,61,95,141,245,388,593,978,1501 -,India,South-East Asia Region,,,,,,,,,,1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5 -,Germany,European Region,,,,,,,,1,4,4,5,7,8,10,12,12,12,13,14,14,14,14,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,21,26,57,57,129,157 -,Philippines,Western Pacific Region,,,,,,,,,,1,1,1,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 -,Spain,European Region,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,12,25,32,45,45,114 -,United Kingdom,European Region,,,,,,,,,,,,2,2,2,2,2,2,3,3,3,4,8,8,9,9,9,9,9,9,9,9,9,9,9,9,13,13,13,16,20,23,36,39 -,Sweden,European Region,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,7,12,13,14,15 -,Switzerland,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,6,10,18,26,30 -,Austria,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,2,4,5,10,10,18 -,Norway,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,4,6,15,19,25 -,Kuwait,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,8,12,43,43,45,45,56,56 -,Bahrain,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,26,33,33,38,40,47,49 -,United Arab Emirates,Eastern Mediterranean Region,,,,,,,,,4,4,4,4,5,5,5,5,5,5,7,7,7,8,8,8,8,8,8,9,9,9,9,9,11,13,13,13,13,13,19,19,19,21,21 -,Israel,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,2,2,2,3,5,7,7,10 -,Iraq,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,5,6,7,8,13,19,26 -,Oman,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,4,4,6,6,6,6,6 -,Lebanon,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,2,2,2,2,10,13 -,Pakistan,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,2,2,4,4,5 -,Egypt,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2 -,Croatia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,3,3,5,7,7,9 -,Greece,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,3,3,3,7,7 -,Finland,European Region,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,6,7 -,Algeria,African Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1,5 -,Brazil,Region of the Americas,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,2,2,2 -,Russian,European Region,,,,,,,,,,,,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3 -,Belgium,European Region,,,,,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,8 -,Denmark,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,2,3,4,5 -,Estonia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1 -,Georgia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,2,3,3,3 -,North Macedonia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1 -,Romania,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,3,3,3,3 -,Afghanistan,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1,1,1 -,New Zealand,Western Pacific Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,2 -,Belarus,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1 -,Lithuania,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1 -,Netherlands,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,2,7,13,18 -,Nigeria,African Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1 -,Mexico,Region of the Americas,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,2,5,5 -,San Marino,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,8 -,Azerbaijan,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,3,3 -,Ireland,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1 -,Monaco,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1 -,Qatar,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,3,7 -,Ecuador,Region of the Americas,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,6 -,Czechia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,3 -,Iceland,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,9 -,Armenia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1 -,Luxembourg,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1 -,Indonesia,South-East Asia Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,2 -,Dominican Republic,Region of the Americas,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1 -,Portugal,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2 -,Andorra,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -,Latvia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -,Jordan,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -,Morocco,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -,Saudi Arabia,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -,Tunisia,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -,Senegal,African Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -Case on an international conveyance,Other,Other,,,,,,,,,,,,,,,,,20,61,64,64,70,135,175,174,218,218,355,454,454,542,621,634,634,634,695,691,691,705,705,705,706,706,706
\ No newline at end of file |