diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/.ipynb_checkpoints/04数组的创建-checkpoint.ipynb b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/.ipynb_checkpoints/04数组的创建-checkpoint.ipynb new file mode 100644 index 0000000..992027d --- /dev/null +++ b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/.ipynb_checkpoints/04数组的创建-checkpoint.ipynb @@ -0,0 +1,617 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "[toc]\n", + "\n", + "---\n", + "# 数组的创建\n", + "\n", + "导入 numpy。\n", + "\n", + "```\n", + "import numpy as np\n", + "```\n", + "\n", + "numpy 提供的最重要的数据结构是`ndarray`,它是 python 中`list`的扩展。\n", + "\n", + "## 1. 依据现有数据来创建 ndarray\n", + "\n", + "### **(a)通过array()函数进行创建。**\n", + "\n", + "```python\n", + "def array(p_object, dtype=None, copy=True, order='K', subok=False, ndmin=0): \n", + "``` \n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "# 创建一维数组\n", + "a = np.array([0, 1, 2, 3, 4])\n", + "b = np.array((0, 1, 2, 3, 4))\n", + "print(a, type(a))\n", + "# [0 1 2 3 4] \n", + "print(b, type(b))\n", + "# [0 1 2 3 4] \n", + "\n", + "# 创建二维数组\n", + "c = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "print(c, type(c))\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]] \n", + "\n", + "# 创建三维数组\n", + "d = np.array([[(1.5, 2, 3), (4, 5, 6)],\n", + " [(3, 2, 1), (4, 5, 6)]])\n", + "print(d, type(d))\n", + "# [[[1.5 2. 3. ]\n", + "# [4. 5. 6. ]]\n", + "#\n", + "# [[3. 2. 1. ]\n", + "# [4. 5. 6. ]]] \n", + "```\n", + "\n", + "### **(b)通过asarray()函数进行创建**\n", + "\n", + "`array()`和`asarray()`都可以将结构数据转化为 ndarray,但是`array()`和`asarray()`主要区别就是当数据源是**ndarray** 时,`array()`仍然会 copy 出一个副本,占用新的内存,但不改变 dtype 时 `asarray()`不会。\n", + "\n", + "```python\n", + "def asarray(a, dtype=None, order=None):\n", + " return array(a, dtype, copy=False, order=order)\n", + "```\n", + "\n", + "【例】`array()`和`asarray()`都可以将结构数据转化为 ndarray\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]\n", + "y = np.array(x)\n", + "z = np.asarray(x)\n", + "x[1][2] = 2\n", + "print(x,type(x))\n", + "# [[1, 1, 1], [1, 1, 2], [1, 1, 1]] \n", + "\n", + "print(y,type(y))\n", + "# [[1 1 1]\n", + "# [1 1 1]\n", + "# [1 1 1]] \n", + "\n", + "print(z,type(z))\n", + "# [[1 1 1]\n", + "# [1 1 1]\n", + "# [1 1 1]] \n", + "```\n", + "\n", + "【例】`array()`和`asarray()`的区别。(`array()`和`asarray()`主要区别就是当数据源是**ndarray** 时,`array()`仍然会 copy 出一个副本,占用新的内存,但不改变 dtype 时 `asarray()`不会。)\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])\n", + "y = np.array(x)\n", + "z = np.asarray(x)\n", + "w = np.asarray(x, dtype=np.int)\n", + "x[1][2] = 2\n", + "print(x,type(x),x.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 2]\n", + "# [1 1 1]] int32\n", + "\n", + "print(y,type(y),y.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 1]\n", + "# [1 1 1]] int32\n", + "\n", + "print(z,type(z),z.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 2]\n", + "# [1 1 1]] int32\n", + "\n", + "print(w,type(w),w.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 2]\n", + "# [1 1 1]] int32\n", + "```\n", + "\n", + "\n", + "【例】更改为较大的dtype时,其大小必须是array的最后一个axis的总大小(以字节为单位)的除数\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])\n", + "print(x, x.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 1]\n", + "# [1 1 1]] int32\n", + "x.dtype = np.float\n", + "\n", + "# ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.\n", + "```\n", + "\n", + "### **(c)通过fromfunction()函数进行创建**\n", + "\n", + "给函数绘图的时候可能会用到`fromfunction()`,该函数可从函数中创建数组。\n", + "\n", + "```python\n", + "def fromfunction(function, shape, **kwargs):\n", + "```\n", + "\n", + "\n", + "【例】通过在每个坐标上执行一个函数来构造数组。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "def f(x, y):\n", + " return 10 * x + y\n", + "\n", + "x = np.fromfunction(f, (5, 4), dtype=int)\n", + "print(x)\n", + "# [[ 0 1 2 3]\n", + "# [10 11 12 13]\n", + "# [20 21 22 23]\n", + "# [30 31 32 33]\n", + "# [40 41 42 43]]\n", + "\n", + "x = np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)\n", + "print(x)\n", + "# [[ True False False]\n", + "# [False True False]\n", + "# [False False True]]\n", + "\n", + "x = np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)\n", + "print(x)\n", + "# [[0 1 2]\n", + "# [1 2 3]\n", + "# [2 3 4]]\n", + "```\n", + "\n", + "\n", + "\n", + "## 2. 依据 ones 和 zeros 填充方式\n", + "\n", + "在机器学习任务中经常做的一件事就是初始化参数,需要用常数值或者随机值来创建一个固定大小的矩阵。\n", + "\n", + "### **(a)零数组**\n", + "\n", + "- `zeros()`函数:返回给定形状和类型的零数组。\n", + "- `zeros_like()`函数:返回与给定数组形状和类型相同的零数组。\n", + "\n", + "```python\n", + "def zeros(shape, dtype=None, order='C'):\n", + "def zeros_like(a, dtype=None, order='K', subok=True, shape=None):\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.zeros(5)\n", + "print(x) # [0. 0. 0. 0. 0.]\n", + "x = np.zeros([2, 3])\n", + "print(x)\n", + "# [[0. 0. 0.]\n", + "# [0. 0. 0.]]\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.zeros_like(x)\n", + "print(y)\n", + "# [[0 0 0]\n", + "# [0 0 0]]\n", + "```\n", + "\n", + "### **(b)1数组**\n", + "\n", + "- `ones()`函数:返回给定形状和类型的1数组。\n", + "- `ones_like()`函数:返回与给定数组形状和类型相同的1数组。\n", + "\n", + "```python\n", + "def ones(shape, dtype=None, order='C'):\n", + "def ones_like(a, dtype=None, order='K', subok=True, shape=None):\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.ones(5)\n", + "print(x) # [1. 1. 1. 1. 1.]\n", + "x = np.ones([2, 3])\n", + "print(x)\n", + "# [[1. 1. 1.]\n", + "# [1. 1. 1.]]\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.ones_like(x)\n", + "print(y)\n", + "# [[1 1 1]\n", + "# [1 1 1]]\n", + "```\n", + "\n", + "### **(c)空数组**\n", + "\n", + "- `empty()`函数:返回一个空数组,数组元素为随机数。\n", + "- `empty_like`函数:返回与给定数组具有相同形状和类型的新数组。\n", + "\n", + "```python\n", + "def empty(shape, dtype=None, order='C'): \n", + "def empty_like(prototype, dtype=None, order='K', subok=True, shape=None):\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.empty(5)\n", + "print(x)\n", + "# [1.95821574e-306 1.60219035e-306 1.37961506e-306 \n", + "# 9.34609790e-307 1.24610383e-306]\n", + "\n", + "x = np.empty((3, 2))\n", + "print(x)\n", + "# [[1.60220393e-306 9.34587382e-307]\n", + "# [8.45599367e-307 7.56598449e-307]\n", + "# [1.33509389e-306 3.59412896e-317]]\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.empty_like(x)\n", + "print(y)\n", + "# [[ 7209029 6422625 6619244]\n", + "# [ 100 707539280 504]]\n", + "```\n", + "\n", + "### **(d)单位数组**\n", + "\n", + "- `eye()`函数:返回一个对角线上为1,其它地方为零的单位数组。\n", + "- `identity()`函数:返回一个方的单位数组。\n", + "\n", + "```python\n", + "def eye(N, M=None, k=0, dtype=float, order='C'):\n", + "def identity(n, dtype=None):\n", + "```\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.eye(4)\n", + "print(x)\n", + "# [[1. 0. 0. 0.]\n", + "# [0. 1. 0. 0.]\n", + "# [0. 0. 1. 0.]\n", + "# [0. 0. 0. 1.]]\n", + "\n", + "x = np.eye(2, 3)\n", + "print(x)\n", + "# [[1. 0. 0.]\n", + "# [0. 1. 0.]]\n", + "\n", + "x = np.identity(4)\n", + "print(x)\n", + "# [[1. 0. 0. 0.]\n", + "# [0. 1. 0. 0.]\n", + "# [0. 0. 1. 0.]\n", + "# [0. 0. 0. 1.]]\n", + "```\n", + "\n", + "### **(e)对角数组**\n", + "\n", + "- `diag()`函数:提取对角线或构造对角数组。\n", + "\n", + "```python\n", + "def diag(v, k=0):\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(9).reshape((3, 3))\n", + "print(x)\n", + "# [[0 1 2]\n", + "# [3 4 5]\n", + "# [6 7 8]]\n", + "print(np.diag(x)) # [0 4 8]\n", + "print(np.diag(x, k=1)) # [1 5]\n", + "print(np.diag(x, k=-1)) # [3 7]\n", + "\n", + "v = [1, 3, 5, 7]\n", + "x = np.diag(v)\n", + "print(x)\n", + "# [[1 0 0 0]\n", + "# [0 3 0 0]\n", + "# [0 0 5 0]\n", + "# [0 0 0 7]]\n", + "```\n", + "\n", + "### **(f)常数数组**\n", + "\n", + "- `full()`函数:返回一个常数数组。\n", + "- `full_like()`函数:返回与给定数组具有相同形状和类型的常数数组。\n", + "\n", + "```python\n", + "def full(shape, fill_value, dtype=None, order='C'):\n", + "def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None):\n", + "```\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.full((2,), 7)\n", + "print(x)\n", + "# [7 7]\n", + "\n", + "x = np.full(2, 7)\n", + "print(x)\n", + "# [7 7]\n", + "\n", + "x = np.full((2, 7), 7)\n", + "print(x)\n", + "# [[7 7 7 7 7 7 7]\n", + "# [7 7 7 7 7 7 7]]\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.full_like(x, 7)\n", + "print(y)\n", + "# [[7 7 7]\n", + "# [7 7 7]]\n", + "```\n", + "\n", + "\n", + "\n", + "## 3. 利用数值范围来创建ndarray\n", + " - `arange()`函数:返回给定间隔内的均匀间隔的值。\n", + " - `linspace()`函数:返回指定间隔内的等间隔数字。\n", + " - `logspace()`函数:返回数以对数刻度均匀分布。\n", + " - `numpy.random.rand()` 返回一个由[0,1)内的随机数组成的数组。\n", + "\n", + "```python\n", + "def arange([start,] stop[, step,], dtype=None): \n", + "def linspace(start, stop, num=50, endpoint=True, retstep=False, \n", + " dtype=None, axis=0):\n", + "def logspace(start, stop, num=50, endpoint=True, base=10.0, \n", + " dtype=None, axis=0):\n", + "def rand(d0, d1, ..., dn): \n", + "```\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(5)\n", + "print(x) # [0 1 2 3 4]\n", + "\n", + "x = np.arange(3, 7, 2)\n", + "print(x) # [3 5]\n", + "\n", + "x = np.linspace(start=0, stop=2, num=9)\n", + "print(x) \n", + "# [0. 0.25 0.5 0.75 1. 1.25 1.5 1.75 2. ]\n", + "\n", + "x = np.logspace(0, 1, 5)\n", + "print(np.around(x, 2))\n", + "# [ 1. 1.78 3.16 5.62 10. ] \n", + " #np.around 返回四舍五入后的值,可指定精度。\n", + " # around(a, decimals=0, out=None)\n", + " # a 输入数组\n", + " # decimals 要舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置\n", + "\n", + "\n", + "x = np.linspace(start=0, stop=1, num=5)\n", + "x = [10 ** i for i in x]\n", + "print(np.around(x, 2))\n", + "# [ 1. 1.78 3.16 5.62 10. ]\n", + "\n", + "x = np.random.random(5)\n", + "print(x)\n", + "# [0.41768753 0.16315577 0.80167915 0.99690199 0.11812291]\n", + "\n", + "x = np.random.random([2, 3])\n", + "print(x)\n", + "# [[0.41151858 0.93785153 0.57031309]\n", + "# [0.13482333 0.20583516 0.45429181]]\n", + "```\n", + "\n", + "\n", + "\n", + "---\n", + "## 4. 结构数组的创建\n", + "\n", + "结构数组,首先需要定义结构,然后利用`np.array()`来创建数组,其参数`dtype`为定义的结构。\n", + "\n", + "### **(a)利用字典来定义结构**\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "personType = np.dtype({\n", + " 'names': ['name', 'age', 'weight'],\n", + " 'formats': ['U30', 'i8', 'f8']})\n", + "\n", + "a = np.array([('Liming', 24, 63.9), ('Mike', 15, 67.), ('Jan', 34, 45.8)],\n", + " dtype=personType)\n", + "print(a, type(a))\n", + "# [('Liming', 24, 63.9) ('Mike', 15, 67. ) ('Jan', 34, 45.8)]\n", + "# \n", + "```\n", + "\n", + "### **(b)利用包含多个元组的列表来定义结构**\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "personType = np.dtype([('name', 'U30'), ('age', 'i8'), ('weight', 'f8')])\n", + "a = np.array([('Liming', 24, 63.9), ('Mike', 15, 67.), ('Jan', 34, 45.8)],\n", + " dtype=personType)\n", + "print(a, type(a))\n", + "# [('Liming', 24, 63.9) ('Mike', 15, 67. ) ('Jan', 34, 45.8)]\n", + "# \n", + "\n", + "# 结构数组的取值方式和一般数组差不多,可以通过下标取得元素:\n", + "print(a[0])\n", + "# ('Liming', 24, 63.9)\n", + "\n", + "print(a[-2:])\n", + "# [('Mike', 15, 67. ) ('Jan', 34, 45.8)]\n", + "\n", + "# 我们可以使用字段名作为下标获取对应的值\n", + "print(a['name'])\n", + "# ['Liming' 'Mike' 'Jan']\n", + "print(a['age'])\n", + "# [24 15 34]\n", + "print(a['weight'])\n", + "# [63.9 67. 45.8]\n", + "```\n", + "\n", + "---\n", + "# 数组的属性\n", + "\n", + "在使用 numpy 时,你会想知道数组的某些信息。很幸运,在这个包里边包含了很多便捷的方法,可以给你想要的信息。\n", + "\n", + "\n", + "\n", + " - `numpy.ndarray.ndim`用于返回数组的维数(轴的个数)也称为秩,一维数组的秩为 1,二维数组的秩为 2,以此类推。\n", + " - `numpy.ndarray.shape`表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 `ndim` 属性(秩)。\n", + " - `numpy.ndarray.size`数组中所有元素的总量,相当于数组的`shape`中所有元素的乘积,例如矩阵的元素总量为行与列的乘积。\n", + " - `numpy.ndarray.dtype` `ndarray` 对象的元素类型。\n", + " - `numpy.ndarray.itemsize`以字节的形式返回数组中每一个元素的大小。\n", + "\n", + "```python\n", + "class ndarray(object):\n", + " shape = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + " dtype = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + " size = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + " ndim = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + " itemsize = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 4, 5])\n", + "print(a.shape) # (5,)\n", + "print(a.dtype) # int32\n", + "print(a.size) # 5\n", + "print(a.ndim) # 1\n", + "print(a.itemsize) # 4\n", + "\n", + "b = np.array([[1, 2, 3], [4, 5, 6.0]])\n", + "print(b.shape) # (2, 3)\n", + "print(b.dtype) # float64\n", + "print(b.size) # 6\n", + "print(b.ndim) # 2\n", + "print(b.itemsize) # 8\n", + "```\n", + "\n", + "在`ndarray`中所有元素必须是同一类型,否则会自动向下转换,`int->float->str`。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 4, 5])\n", + "print(a) # [1 2 3 4 5]\n", + "b = np.array([1, 2, 3, 4, '5'])\n", + "print(b) # ['1' '2' '3' '4' '5']\n", + "c = np.array([1, 2, 3, 4, 5.0])\n", + "print(c) # [1. 2. 3. 4. 5.]\n", + "```\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "307.188px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/.ipynb_checkpoints/练习-数组的创建-checkpoint.ipynb b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/.ipynb_checkpoints/练习-数组的创建-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/.ipynb_checkpoints/练习-数组的创建-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/.ipynb_checkpoints/练习-数组的创建-答案-checkpoint.ipynb b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/.ipynb_checkpoints/练习-数组的创建-答案-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/.ipynb_checkpoints/练习-数组的创建-答案-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/01常量.ipynb b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/01常量.ipynb new file mode 100644 index 0000000..8708881 --- /dev/null +++ b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/01常量.ipynb @@ -0,0 +1,148 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 常量\n", + "\n", + "## numpy.nan\n", + "\n", + "- 表示空值。\n", + "\n", + "```\n", + "nan = NaN = NAN\n", + "```\n", + "\n", + "\n", + "【例】两个`numpy.nan`是不相等的。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "print(np.nan == np.nan) # False\n", + "print(np.nan != np.nan) # True\n", + "```\n", + "\n", + "- `numpy.isnan(x, *args, **kwargs)` Test element-wise for NaN and return result as a boolean array.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 1, 8, np.nan, 10])\n", + "print(x)\n", + "# [ 1. 1. 8. nan 10.]\n", + "\n", + "y = np.isnan(x)\n", + "print(y)\n", + "# [False False False True False]\n", + "\n", + "z = np.count_nonzero(y)\n", + "print(z) # 1\n", + "```\n", + "\n", + "\n", + "\n", + "## numpy.inf\n", + "- 表示正无穷大。\n", + "\n", + "```\n", + "Inf = inf = infty = Infinity = PINF\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "\n", + "```\n", + "\n", + "## numpy.pi\n", + "\n", + "- 表示圆周率\n", + "\n", + "```python\n", + "pi = 3.1415926535897932384626433...\n", + "```\n", + "\n", + "## numpy.e\n", + "\n", + "- 表示自然常数\n", + "\n", + "```python\n", + "e = 2.71828182845904523536028747135266249775724709369995...\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/02数据类型.ipynb b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/02数据类型.ipynb new file mode 100644 index 0000000..94a4686 --- /dev/null +++ b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/02数据类型.ipynb @@ -0,0 +1,250 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 数据类型\n", + "\n", + "## 常见数据类型\n", + "\n", + "Python 原生的数据类型相对较少, bool、int、float、str等。这在不需要关心数据在计算机中表示的所有方式的应用中是方便的。然而,对于科学计算,通常需要更多的控制。为了加以区分 numpy 在这些类型名称末尾都加了“_”。\n", + "\n", + "下表列举了常用 numpy 基本类型。\n", + "\n", + "\n", + "类型 | 备注 | 说明 \n", + "---|---|---\n", + "bool_ = bool8 | 8位 | 布尔类型\n", + "int8 = byte | 8位 | 整型\n", + "int16 = short |\t16位| 整型\n", + "int32 = intc | 32位| 整型\n", + "int_ = int64 = long = int0 = intp | 64位| 整型\n", + "uint8 = ubyte |8位 | 无符号整型\n", + "uint16 = ushort|16位| 无符号整型\n", + "uint32 = uintc|32位| 无符号整型\n", + "uint64 = uintp = uint0 = uint| 64位| 无符号整型\n", + "float16 = half|16位 | 浮点型\n", + "float32 = single| 32位| 浮点型\n", + "float_ = float64 = double| 64位| 浮点型\n", + "str_ = unicode_ = str0 = unicode| |Unicode 字符串\n", + "datetime64| |日期时间类型\n", + "timedelta64| |表示两个时间之间的间隔\n", + "\n", + "\n", + "\n", + "## 创建数据类型\n", + "\n", + "numpy 的数值类型实际上是 dtype 对象的实例。\n", + "\n", + "```python\n", + "class dtype(object):\n", + " def __init__(self, obj, align=False, copy=False):\n", + " pass\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "每个内建类型都有一个唯一定义它的字符代码,如下:\n", + "\n", + "字符 | \t对应类型|备注\n", + "---|---|---\n", + "b\t|boolean | 'b1'\n", + "i\t|signed integer | 'i1', 'i2', 'i4', 'i8'\n", + "u\t|unsigned integer | 'u1', 'u2' ,'u4' ,'u8'\n", + "f\t|floating-point | 'f2', 'f4', 'f8'\n", + "c\t|complex floating-point |\n", + "m\t|timedelta64 |表示两个时间之间的间隔\n", + "M\t|datetime64 |日期时间类型\n", + "O\t|object |\n", + "S\t|(byte-)string | S3表示长度为3的字符串\n", + "U\t|Unicode | Unicode 字符串\n", + "V\t|void\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.dtype('b1')\n", + "print(a.type) # \n", + "print(a.itemsize) # 1\n", + "\n", + "a = np.dtype('i1')\n", + "print(a.type) # \n", + "print(a.itemsize) # 1\n", + "a = np.dtype('i2')\n", + "print(a.type) # \n", + "print(a.itemsize) # 2\n", + "a = np.dtype('i4')\n", + "print(a.type) # \n", + "print(a.itemsize) # 4\n", + "a = np.dtype('i8')\n", + "print(a.type) # \n", + "print(a.itemsize) # 8\n", + "\n", + "a = np.dtype('u1')\n", + "print(a.type) # \n", + "print(a.itemsize) # 1\n", + "a = np.dtype('u2')\n", + "print(a.type) # \n", + "print(a.itemsize) # 2\n", + "a = np.dtype('u4')\n", + "print(a.type) # \n", + "print(a.itemsize) # 4\n", + "a = np.dtype('u8')\n", + "print(a.type) # \n", + "print(a.itemsize) # 8\n", + "\n", + "a = np.dtype('f2')\n", + "print(a.type) # \n", + "print(a.itemsize) # 2\n", + "a = np.dtype('f4')\n", + "print(a.type) # \n", + "print(a.itemsize) # 4\n", + "a = np.dtype('f8')\n", + "print(a.type) # \n", + "print(a.itemsize) # 8\n", + "\n", + "a = np.dtype('S')\n", + "print(a.type) # \n", + "print(a.itemsize) # 0\n", + "a = np.dtype('S3')\n", + "print(a.type) # \n", + "print(a.itemsize) # 3\n", + "\n", + "a = np.dtype('U3')\n", + "print(a.type) # \n", + "print(a.itemsize) # 12\n", + "```\n", + "\n", + "## 数据类型信息\n", + "\n", + "Python 的浮点数通常是64位浮点数,几乎等同于 `np.float64`。\n", + "\n", + "NumPy和Python整数类型的行为在整数溢出方面存在显着差异,与 NumPy 不同,Python 的`int` 是灵活的。这意味着Python整数可以扩展以容纳任何整数并且不会溢出。\n", + "\n", + "Machine limits for integer types.\n", + "```python\n", + "class iinfo(object):\n", + " def __init__(self, int_type):\n", + " pass\n", + " def min(self):\n", + " pass\n", + " def max(self):\n", + " pass\n", + "```\n", + "【例】\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "ii16 = np.iinfo(np.int16)\n", + "print(ii16.min) # -32768\n", + "print(ii16.max) # 32767\n", + "\n", + "ii32 = np.iinfo(np.int32)\n", + "print(ii32.min) # -2147483648\n", + "print(ii32.max) # 2147483647\n", + "```\n", + "\n", + "Machine limits for floating point types.\n", + "```python\n", + "class finfo(object):\n", + " def _init(self, dtype):\n", + "```\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "ff16 = np.finfo(np.float16)\n", + "print(ff16.bits) # 16\n", + "print(ff16.min) # -65500.0\n", + "print(ff16.max) # 65500.0\n", + "print(ff16.eps) # 0.000977\n", + "\n", + "ff32 = np.finfo(np.float32)\n", + "print(ff32.bits) # 32\n", + "print(ff32.min) # -3.4028235e+38\n", + "print(ff32.max) # 3.4028235e+38\n", + "print(ff32.eps) # 1.1920929e-07\n", + "```\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "218.2px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/03时间日期和时间增量.ipynb b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/03时间日期和时间增量.ipynb new file mode 100644 index 0000000..87f74a3 --- /dev/null +++ b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/03时间日期和时间增量.ipynb @@ -0,0 +1,356 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 时间日期和时间增量\n", + "\n", + "## datetime64 基础\n", + "\n", + "在 numpy 中,我们很方便的将字符串转换成时间日期类型 `datetime64`(`datetime` 已被 python 包含的日期时间库所占用)。\n", + "\n", + "`datatime64`是带单位的日期时间类型,其单位如下:\n", + "\n", + "日期单位 | 代码含义|时间单位 | 代码含义\n", + ":---:|:---:|:---:|:---:\n", + "Y | 年 |h | 小时\n", + "M | 月 |m | 分钟\n", + "W | 周 |s | 秒\n", + "D | 天 |ms | 毫秒\n", + "- | - |us | 微秒\n", + "- | - |ns | 纳秒\n", + "- | - |ps | 皮秒\n", + "- | - |fs | 飞秒\n", + "- | - |as | 阿托秒\n", + "\n", + "注意:\n", + "- 1秒 = 1000 毫秒(milliseconds)\n", + "- 1毫秒 = 1000 微秒(microseconds)\n", + "\n", + "【例】从字符串创建 datetime64 类型时,默认情况下,numpy 会根据字符串自动选择对应的单位。\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.datetime64('2020-03-01')\n", + "print(a, a.dtype) # 2020-03-01 datetime64[D]\n", + "\n", + "a = np.datetime64('2020-03')\n", + "print(a, a.dtype) # 2020-03 datetime64[M]\n", + "\n", + "a = np.datetime64('2020-03-08 20:00:05')\n", + "print(a, a.dtype) # 2020-03-08T20:00:05 datetime64[s]\n", + "\n", + "a = np.datetime64('2020-03-08 20:00')\n", + "print(a, a.dtype) # 2020-03-08T20:00 datetime64[m]\n", + "\n", + "a = np.datetime64('2020-03-08 20')\n", + "print(a, a.dtype) # 2020-03-08T20 datetime64[h]\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "【例】从字符串创建 datetime64 类型时,可以强制指定使用的单位。\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.datetime64('2020-03', 'D')\n", + "print(a, a.dtype) # 2020-03-01 datetime64[D]\n", + "\n", + "a = np.datetime64('2020-03', 'Y')\n", + "print(a, a.dtype) # 2020 datetime64[Y]\n", + "\n", + "print(np.datetime64('2020-03') == np.datetime64('2020-03-01')) # True\n", + "print(np.datetime64('2020-03') == np.datetime64('2020-03-02')) #False\n", + "```\n", + "\n", + "由上例可以看出,2019-03 和 2019-03-01 所表示的其实是同一个时间。\n", + "事实上,如果两个 datetime64 对象具有不同的单位,它们可能仍然代表相同的时刻。并且从较大的单位(如月份)转换为较小的单位(如天数)是安全的。\n", + "\n", + "\n", + "【例】从字符串创建 datetime64 数组时,如果单位不统一,则一律转化成其中最小的单位。\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.array(['2020-03', '2020-03-08', '2020-03-08 20:00'], dtype='datetime64')\n", + "print(a, a.dtype)\n", + "# ['2020-03-01T00:00' '2020-03-08T00:00' '2020-03-08T20:00'] datetime64[m]\n", + "```\n", + "\n", + "\n", + "【例】使用`arange()`创建 datetime64 数组,用于生成日期范围。\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.arange('2020-08-01', '2020-08-10', dtype=np.datetime64)\n", + "print(a)\n", + "# ['2020-08-01' '2020-08-02' '2020-08-03' '2020-08-04' '2020-08-05'\n", + "# '2020-08-06' '2020-08-07' '2020-08-08' '2020-08-09']\n", + "print(a.dtype) # datetime64[D]\n", + "\n", + "a = np.arange('2020-08-01 20:00', '2020-08-10', dtype=np.datetime64)\n", + "print(a)\n", + "# ['2020-08-01T20:00' '2020-08-01T20:01' '2020-08-01T20:02' ...\n", + "# '2020-08-09T23:57' '2020-08-09T23:58' '2020-08-09T23:59']\n", + "print(a.dtype) # datetime64[m]\n", + "\n", + "a = np.arange('2020-05', '2020-12', dtype=np.datetime64)\n", + "print(a)\n", + "# ['2020-05' '2020-06' '2020-07' '2020-08' '2020-09' '2020-10' '2020-11']\n", + "print(a.dtype) # datetime64[M]\n", + "```\n", + "\n", + "## datetime64 和 timedelta64 运算\n", + "\n", + "【例】timedelta64 表示两个 datetime64 之间的差。timedelta64 也是带单位的,并且和相减运算中的两个 datetime64 中的较小的单位保持一致。\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.datetime64('2020-03-08') - np.datetime64('2020-03-07')\n", + "b = np.datetime64('2020-03-08') - np.datetime64('202-03-07 08:00')\n", + "c = np.datetime64('2020-03-08') - np.datetime64('2020-03-07 23:00', 'D')\n", + "\n", + "print(a, a.dtype) # 1 days timedelta64[D]\n", + "print(b, b.dtype) # 956178240 minutes timedelta64[m]\n", + "print(c, c.dtype) # 1 days timedelta64[D]\n", + "\n", + "a = np.datetime64('2020-03') + np.timedelta64(20, 'D')\n", + "b = np.datetime64('2020-06-15 00:00') + np.timedelta64(12, 'h')\n", + "print(a, a.dtype) # 2020-03-21 datetime64[D]\n", + "print(b, b.dtype) # 2020-06-15T12:00 datetime64[m]\n", + "```\n", + "\n", + "【例】生成 timedelta64时,要注意年('Y')和月('M')这两个单位无法和其它单位进行运算(一年有几天?一个月有几个小时?这些都是不确定的)。\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.timedelta64(1, 'Y')\n", + "b = np.timedelta64(a, 'M')\n", + "print(a) # 1 years\n", + "print(b) # 12 months\n", + "\n", + "c = np.timedelta64(1, 'h')\n", + "d = np.timedelta64(c, 'm')\n", + "print(c) # 1 hours\n", + "print(d) # 60 minutes\n", + "\n", + "print(np.timedelta64(a, 'D'))\n", + "# TypeError: Cannot cast NumPy timedelta64 scalar from metadata [Y] to [D] according to the rule 'same_kind'\n", + "\n", + "print(np.timedelta64(b, 'D'))\n", + "# TypeError: Cannot cast NumPy timedelta64 scalar from metadata [M] to [D] according to the rule 'same_kind'\n", + "```\n", + "\n", + "\n", + "【例】timedelta64 的运算。\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.timedelta64(1, 'Y')\n", + "b = np.timedelta64(6, 'M')\n", + "c = np.timedelta64(1, 'W')\n", + "d = np.timedelta64(1, 'D')\n", + "e = np.timedelta64(10, 'D')\n", + "\n", + "print(a) # 1 years\n", + "print(b) # 6 months\n", + "print(a + b) # 18 months\n", + "print(a - b) # 6 months\n", + "print(2 * a) # 2 years\n", + "print(a / b) # 2.0\n", + "print(c / d) # 7.0\n", + "print(c % e) # 7 days\n", + "```\n", + "\n", + "【例】numpy.datetime64 与 datetime.datetime 相互转换\n", + "```python\n", + "import numpy as np\n", + "import datetime\n", + "\n", + "dt = datetime.datetime(year=2020, month=6, day=1, hour=20, minute=5, second=30)\n", + "dt64 = np.datetime64(dt, 's')\n", + "print(dt64, dt64.dtype)\n", + "# 2020-06-01T20:05:30 datetime64[s]\n", + "\n", + "dt2 = dt64.astype(datetime.datetime)\n", + "print(dt2, type(dt2))\n", + "# 2020-06-01 20:05:30 \n", + "```\n", + "\n", + "## datetime64 的应用\n", + "\n", + "为了允许在只有一周中某些日子有效的上下文中使用日期时间,NumPy包含一组“busday”(工作日)功能。\n", + "\n", + "- `numpy.busday_offset(dates, offsets, roll='raise', weekmask='1111100', holidays=None, busdaycal=None, out=None)` First adjusts the date to fall on a valid day according to the roll rule, then applies offsets to the given dates counted in valid days.\n", + "\n", + "参数`roll`:{'raise', 'nat', 'forward', 'following', 'backward', 'preceding', 'modifiedfollowing', 'modifiedpreceding'}\n", + "- 'raise' means to raise an exception for an invalid day.\n", + "- 'nat' means to return a NaT (not-a-time) for an invalid day.\n", + "- 'forward' and 'following' mean to take the first valid day later in time.\n", + "- 'backward' and 'preceding' mean to take the first valid day earlier in time.\n", + "\n", + "\n", + "【例】将指定的偏移量应用于工作日,单位天('D')。计算下一个工作日,如果当前日期为非工作日,默认报错。可以指定 `forward` 或 `backward` 规则来避免报错。(一个是向前取第一个有效的工作日,一个是向后取第一个有效的工作日)\n", + "```python\n", + "import numpy as np\n", + "\n", + "# 2020-07-10 星期五\n", + "a = np.busday_offset('2020-07-10', offsets=1)\n", + "print(a) # 2020-07-13\n", + "\n", + "a = np.busday_offset('2020-07-11', offsets=1)\n", + "print(a)\n", + "# ValueError: Non-business day date in busday_offset\n", + "\n", + "a = np.busday_offset('2020-07-11', offsets=0, roll='forward')\n", + "b = np.busday_offset('2020-07-11', offsets=0, roll='backward')\n", + "print(a) # 2020-07-13\n", + "print(b) # 2020-07-10\n", + "\n", + "a = np.busday_offset('2020-07-11', offsets=1, roll='forward')\n", + "b = np.busday_offset('2020-07-11', offsets=1, roll='backward')\n", + "print(a) # 2020-07-14\n", + "print(b) # 2020-07-13\n", + "```\n", + "\n", + "可以指定偏移量为 0 来获取当前日期向前或向后最近的工作日,当然,如果当前日期本身就是工作日,则直接返回当前日期。\n", + "\n", + "- `numpy.is_busday(dates, weekmask='1111100', holidays=None, busdaycal=None, out=None)` Calculates which of the given dates are valid days, and which are not.\n", + "\n", + "【例】返回指定日期是否是工作日。\n", + "```python\n", + "import numpy as np\n", + "\n", + "# 2020-07-10 星期五\n", + "a = np.is_busday('2020-07-10')\n", + "b = np.is_busday('2020-07-11')\n", + "print(a) # True\n", + "print(b) # False\n", + "```\n", + "\n", + "【例】统计一个 `datetime64[D]` 数组中的工作日天数。\n", + "```python\n", + "import numpy as np\n", + "\n", + "# 2020-07-10 星期五\n", + "begindates = np.datetime64('2020-07-10')\n", + "enddates = np.datetime64('2020-07-20')\n", + "a = np.arange(begindates, enddates, dtype='datetime64')\n", + "b = np.count_nonzero(np.is_busday(a))\n", + "print(a)\n", + "# ['2020-07-10' '2020-07-11' '2020-07-12' '2020-07-13' '2020-07-14'\n", + "# '2020-07-15' '2020-07-16' '2020-07-17' '2020-07-18' '2020-07-19']\n", + "print(b) # 6\n", + "```\n", + "\n", + "\n", + "【例】自定义周掩码值,即指定一周中哪些星期是工作日。\n", + "```python\n", + "import numpy as np\n", + "\n", + "# 2020-07-10 星期五\n", + "a = np.is_busday('2020-07-10', weekmask=[1, 1, 1, 1, 1, 0, 0])\n", + "b = np.is_busday('2020-07-10', weekmask=[1, 1, 1, 1, 0, 0, 1])\n", + "print(a) # True\n", + "print(b) # False\n", + "```\n", + "\n", + "- `numpy.busday_count(begindates, enddates, weekmask='1111100', holidays=[], busdaycal=None, out=None)`Counts the number of valid days between `begindates` and `enddates`, not including the day of `enddates`.\n", + "\n", + "【例】返回两个日期之间的工作日数量。\n", + "```python\n", + "import numpy as np\n", + "\n", + "# 2020-07-10 星期五\n", + "begindates = np.datetime64('2020-07-10')\n", + "enddates = np.datetime64('2020-07-20')\n", + "a = np.busday_count(begindates, enddates)\n", + "b = np.busday_count(enddates, begindates)\n", + "print(a) # 6\n", + "print(b) # -6\n", + "```\n", + "\n", + "\n", + "---\n", + "参考图文\n", + "\n", + "- https://www.jianshu.com/p/336cd77d9914\n", + "- https://www.cnblogs.com/gl1573/p/10549547.html#h2datetime64\n", + "- https://www.numpy.org.cn/reference/arrays/datetime.html#%E6%97%A5%E6%9C%9F%E6%97%B6%E9%97%B4%E5%8D%95%E4%BD%8D\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/04数组的创建.ipynb b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/04数组的创建.ipynb new file mode 100644 index 0000000..992027d --- /dev/null +++ b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/04数组的创建.ipynb @@ -0,0 +1,617 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "[toc]\n", + "\n", + "---\n", + "# 数组的创建\n", + "\n", + "导入 numpy。\n", + "\n", + "```\n", + "import numpy as np\n", + "```\n", + "\n", + "numpy 提供的最重要的数据结构是`ndarray`,它是 python 中`list`的扩展。\n", + "\n", + "## 1. 依据现有数据来创建 ndarray\n", + "\n", + "### **(a)通过array()函数进行创建。**\n", + "\n", + "```python\n", + "def array(p_object, dtype=None, copy=True, order='K', subok=False, ndmin=0): \n", + "``` \n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "# 创建一维数组\n", + "a = np.array([0, 1, 2, 3, 4])\n", + "b = np.array((0, 1, 2, 3, 4))\n", + "print(a, type(a))\n", + "# [0 1 2 3 4] \n", + "print(b, type(b))\n", + "# [0 1 2 3 4] \n", + "\n", + "# 创建二维数组\n", + "c = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "print(c, type(c))\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]] \n", + "\n", + "# 创建三维数组\n", + "d = np.array([[(1.5, 2, 3), (4, 5, 6)],\n", + " [(3, 2, 1), (4, 5, 6)]])\n", + "print(d, type(d))\n", + "# [[[1.5 2. 3. ]\n", + "# [4. 5. 6. ]]\n", + "#\n", + "# [[3. 2. 1. ]\n", + "# [4. 5. 6. ]]] \n", + "```\n", + "\n", + "### **(b)通过asarray()函数进行创建**\n", + "\n", + "`array()`和`asarray()`都可以将结构数据转化为 ndarray,但是`array()`和`asarray()`主要区别就是当数据源是**ndarray** 时,`array()`仍然会 copy 出一个副本,占用新的内存,但不改变 dtype 时 `asarray()`不会。\n", + "\n", + "```python\n", + "def asarray(a, dtype=None, order=None):\n", + " return array(a, dtype, copy=False, order=order)\n", + "```\n", + "\n", + "【例】`array()`和`asarray()`都可以将结构数据转化为 ndarray\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]\n", + "y = np.array(x)\n", + "z = np.asarray(x)\n", + "x[1][2] = 2\n", + "print(x,type(x))\n", + "# [[1, 1, 1], [1, 1, 2], [1, 1, 1]] \n", + "\n", + "print(y,type(y))\n", + "# [[1 1 1]\n", + "# [1 1 1]\n", + "# [1 1 1]] \n", + "\n", + "print(z,type(z))\n", + "# [[1 1 1]\n", + "# [1 1 1]\n", + "# [1 1 1]] \n", + "```\n", + "\n", + "【例】`array()`和`asarray()`的区别。(`array()`和`asarray()`主要区别就是当数据源是**ndarray** 时,`array()`仍然会 copy 出一个副本,占用新的内存,但不改变 dtype 时 `asarray()`不会。)\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])\n", + "y = np.array(x)\n", + "z = np.asarray(x)\n", + "w = np.asarray(x, dtype=np.int)\n", + "x[1][2] = 2\n", + "print(x,type(x),x.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 2]\n", + "# [1 1 1]] int32\n", + "\n", + "print(y,type(y),y.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 1]\n", + "# [1 1 1]] int32\n", + "\n", + "print(z,type(z),z.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 2]\n", + "# [1 1 1]] int32\n", + "\n", + "print(w,type(w),w.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 2]\n", + "# [1 1 1]] int32\n", + "```\n", + "\n", + "\n", + "【例】更改为较大的dtype时,其大小必须是array的最后一个axis的总大小(以字节为单位)的除数\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])\n", + "print(x, x.dtype)\n", + "# [[1 1 1]\n", + "# [1 1 1]\n", + "# [1 1 1]] int32\n", + "x.dtype = np.float\n", + "\n", + "# ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.\n", + "```\n", + "\n", + "### **(c)通过fromfunction()函数进行创建**\n", + "\n", + "给函数绘图的时候可能会用到`fromfunction()`,该函数可从函数中创建数组。\n", + "\n", + "```python\n", + "def fromfunction(function, shape, **kwargs):\n", + "```\n", + "\n", + "\n", + "【例】通过在每个坐标上执行一个函数来构造数组。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "def f(x, y):\n", + " return 10 * x + y\n", + "\n", + "x = np.fromfunction(f, (5, 4), dtype=int)\n", + "print(x)\n", + "# [[ 0 1 2 3]\n", + "# [10 11 12 13]\n", + "# [20 21 22 23]\n", + "# [30 31 32 33]\n", + "# [40 41 42 43]]\n", + "\n", + "x = np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)\n", + "print(x)\n", + "# [[ True False False]\n", + "# [False True False]\n", + "# [False False True]]\n", + "\n", + "x = np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)\n", + "print(x)\n", + "# [[0 1 2]\n", + "# [1 2 3]\n", + "# [2 3 4]]\n", + "```\n", + "\n", + "\n", + "\n", + "## 2. 依据 ones 和 zeros 填充方式\n", + "\n", + "在机器学习任务中经常做的一件事就是初始化参数,需要用常数值或者随机值来创建一个固定大小的矩阵。\n", + "\n", + "### **(a)零数组**\n", + "\n", + "- `zeros()`函数:返回给定形状和类型的零数组。\n", + "- `zeros_like()`函数:返回与给定数组形状和类型相同的零数组。\n", + "\n", + "```python\n", + "def zeros(shape, dtype=None, order='C'):\n", + "def zeros_like(a, dtype=None, order='K', subok=True, shape=None):\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.zeros(5)\n", + "print(x) # [0. 0. 0. 0. 0.]\n", + "x = np.zeros([2, 3])\n", + "print(x)\n", + "# [[0. 0. 0.]\n", + "# [0. 0. 0.]]\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.zeros_like(x)\n", + "print(y)\n", + "# [[0 0 0]\n", + "# [0 0 0]]\n", + "```\n", + "\n", + "### **(b)1数组**\n", + "\n", + "- `ones()`函数:返回给定形状和类型的1数组。\n", + "- `ones_like()`函数:返回与给定数组形状和类型相同的1数组。\n", + "\n", + "```python\n", + "def ones(shape, dtype=None, order='C'):\n", + "def ones_like(a, dtype=None, order='K', subok=True, shape=None):\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.ones(5)\n", + "print(x) # [1. 1. 1. 1. 1.]\n", + "x = np.ones([2, 3])\n", + "print(x)\n", + "# [[1. 1. 1.]\n", + "# [1. 1. 1.]]\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.ones_like(x)\n", + "print(y)\n", + "# [[1 1 1]\n", + "# [1 1 1]]\n", + "```\n", + "\n", + "### **(c)空数组**\n", + "\n", + "- `empty()`函数:返回一个空数组,数组元素为随机数。\n", + "- `empty_like`函数:返回与给定数组具有相同形状和类型的新数组。\n", + "\n", + "```python\n", + "def empty(shape, dtype=None, order='C'): \n", + "def empty_like(prototype, dtype=None, order='K', subok=True, shape=None):\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.empty(5)\n", + "print(x)\n", + "# [1.95821574e-306 1.60219035e-306 1.37961506e-306 \n", + "# 9.34609790e-307 1.24610383e-306]\n", + "\n", + "x = np.empty((3, 2))\n", + "print(x)\n", + "# [[1.60220393e-306 9.34587382e-307]\n", + "# [8.45599367e-307 7.56598449e-307]\n", + "# [1.33509389e-306 3.59412896e-317]]\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.empty_like(x)\n", + "print(y)\n", + "# [[ 7209029 6422625 6619244]\n", + "# [ 100 707539280 504]]\n", + "```\n", + "\n", + "### **(d)单位数组**\n", + "\n", + "- `eye()`函数:返回一个对角线上为1,其它地方为零的单位数组。\n", + "- `identity()`函数:返回一个方的单位数组。\n", + "\n", + "```python\n", + "def eye(N, M=None, k=0, dtype=float, order='C'):\n", + "def identity(n, dtype=None):\n", + "```\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.eye(4)\n", + "print(x)\n", + "# [[1. 0. 0. 0.]\n", + "# [0. 1. 0. 0.]\n", + "# [0. 0. 1. 0.]\n", + "# [0. 0. 0. 1.]]\n", + "\n", + "x = np.eye(2, 3)\n", + "print(x)\n", + "# [[1. 0. 0.]\n", + "# [0. 1. 0.]]\n", + "\n", + "x = np.identity(4)\n", + "print(x)\n", + "# [[1. 0. 0. 0.]\n", + "# [0. 1. 0. 0.]\n", + "# [0. 0. 1. 0.]\n", + "# [0. 0. 0. 1.]]\n", + "```\n", + "\n", + "### **(e)对角数组**\n", + "\n", + "- `diag()`函数:提取对角线或构造对角数组。\n", + "\n", + "```python\n", + "def diag(v, k=0):\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(9).reshape((3, 3))\n", + "print(x)\n", + "# [[0 1 2]\n", + "# [3 4 5]\n", + "# [6 7 8]]\n", + "print(np.diag(x)) # [0 4 8]\n", + "print(np.diag(x, k=1)) # [1 5]\n", + "print(np.diag(x, k=-1)) # [3 7]\n", + "\n", + "v = [1, 3, 5, 7]\n", + "x = np.diag(v)\n", + "print(x)\n", + "# [[1 0 0 0]\n", + "# [0 3 0 0]\n", + "# [0 0 5 0]\n", + "# [0 0 0 7]]\n", + "```\n", + "\n", + "### **(f)常数数组**\n", + "\n", + "- `full()`函数:返回一个常数数组。\n", + "- `full_like()`函数:返回与给定数组具有相同形状和类型的常数数组。\n", + "\n", + "```python\n", + "def full(shape, fill_value, dtype=None, order='C'):\n", + "def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None):\n", + "```\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.full((2,), 7)\n", + "print(x)\n", + "# [7 7]\n", + "\n", + "x = np.full(2, 7)\n", + "print(x)\n", + "# [7 7]\n", + "\n", + "x = np.full((2, 7), 7)\n", + "print(x)\n", + "# [[7 7 7 7 7 7 7]\n", + "# [7 7 7 7 7 7 7]]\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.full_like(x, 7)\n", + "print(y)\n", + "# [[7 7 7]\n", + "# [7 7 7]]\n", + "```\n", + "\n", + "\n", + "\n", + "## 3. 利用数值范围来创建ndarray\n", + " - `arange()`函数:返回给定间隔内的均匀间隔的值。\n", + " - `linspace()`函数:返回指定间隔内的等间隔数字。\n", + " - `logspace()`函数:返回数以对数刻度均匀分布。\n", + " - `numpy.random.rand()` 返回一个由[0,1)内的随机数组成的数组。\n", + "\n", + "```python\n", + "def arange([start,] stop[, step,], dtype=None): \n", + "def linspace(start, stop, num=50, endpoint=True, retstep=False, \n", + " dtype=None, axis=0):\n", + "def logspace(start, stop, num=50, endpoint=True, base=10.0, \n", + " dtype=None, axis=0):\n", + "def rand(d0, d1, ..., dn): \n", + "```\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(5)\n", + "print(x) # [0 1 2 3 4]\n", + "\n", + "x = np.arange(3, 7, 2)\n", + "print(x) # [3 5]\n", + "\n", + "x = np.linspace(start=0, stop=2, num=9)\n", + "print(x) \n", + "# [0. 0.25 0.5 0.75 1. 1.25 1.5 1.75 2. ]\n", + "\n", + "x = np.logspace(0, 1, 5)\n", + "print(np.around(x, 2))\n", + "# [ 1. 1.78 3.16 5.62 10. ] \n", + " #np.around 返回四舍五入后的值,可指定精度。\n", + " # around(a, decimals=0, out=None)\n", + " # a 输入数组\n", + " # decimals 要舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置\n", + "\n", + "\n", + "x = np.linspace(start=0, stop=1, num=5)\n", + "x = [10 ** i for i in x]\n", + "print(np.around(x, 2))\n", + "# [ 1. 1.78 3.16 5.62 10. ]\n", + "\n", + "x = np.random.random(5)\n", + "print(x)\n", + "# [0.41768753 0.16315577 0.80167915 0.99690199 0.11812291]\n", + "\n", + "x = np.random.random([2, 3])\n", + "print(x)\n", + "# [[0.41151858 0.93785153 0.57031309]\n", + "# [0.13482333 0.20583516 0.45429181]]\n", + "```\n", + "\n", + "\n", + "\n", + "---\n", + "## 4. 结构数组的创建\n", + "\n", + "结构数组,首先需要定义结构,然后利用`np.array()`来创建数组,其参数`dtype`为定义的结构。\n", + "\n", + "### **(a)利用字典来定义结构**\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "personType = np.dtype({\n", + " 'names': ['name', 'age', 'weight'],\n", + " 'formats': ['U30', 'i8', 'f8']})\n", + "\n", + "a = np.array([('Liming', 24, 63.9), ('Mike', 15, 67.), ('Jan', 34, 45.8)],\n", + " dtype=personType)\n", + "print(a, type(a))\n", + "# [('Liming', 24, 63.9) ('Mike', 15, 67. ) ('Jan', 34, 45.8)]\n", + "# \n", + "```\n", + "\n", + "### **(b)利用包含多个元组的列表来定义结构**\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "personType = np.dtype([('name', 'U30'), ('age', 'i8'), ('weight', 'f8')])\n", + "a = np.array([('Liming', 24, 63.9), ('Mike', 15, 67.), ('Jan', 34, 45.8)],\n", + " dtype=personType)\n", + "print(a, type(a))\n", + "# [('Liming', 24, 63.9) ('Mike', 15, 67. ) ('Jan', 34, 45.8)]\n", + "# \n", + "\n", + "# 结构数组的取值方式和一般数组差不多,可以通过下标取得元素:\n", + "print(a[0])\n", + "# ('Liming', 24, 63.9)\n", + "\n", + "print(a[-2:])\n", + "# [('Mike', 15, 67. ) ('Jan', 34, 45.8)]\n", + "\n", + "# 我们可以使用字段名作为下标获取对应的值\n", + "print(a['name'])\n", + "# ['Liming' 'Mike' 'Jan']\n", + "print(a['age'])\n", + "# [24 15 34]\n", + "print(a['weight'])\n", + "# [63.9 67. 45.8]\n", + "```\n", + "\n", + "---\n", + "# 数组的属性\n", + "\n", + "在使用 numpy 时,你会想知道数组的某些信息。很幸运,在这个包里边包含了很多便捷的方法,可以给你想要的信息。\n", + "\n", + "\n", + "\n", + " - `numpy.ndarray.ndim`用于返回数组的维数(轴的个数)也称为秩,一维数组的秩为 1,二维数组的秩为 2,以此类推。\n", + " - `numpy.ndarray.shape`表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 `ndim` 属性(秩)。\n", + " - `numpy.ndarray.size`数组中所有元素的总量,相当于数组的`shape`中所有元素的乘积,例如矩阵的元素总量为行与列的乘积。\n", + " - `numpy.ndarray.dtype` `ndarray` 对象的元素类型。\n", + " - `numpy.ndarray.itemsize`以字节的形式返回数组中每一个元素的大小。\n", + "\n", + "```python\n", + "class ndarray(object):\n", + " shape = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + " dtype = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + " size = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + " ndim = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + " itemsize = property(lambda self: object(), lambda self, v: None, lambda self: None)\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 4, 5])\n", + "print(a.shape) # (5,)\n", + "print(a.dtype) # int32\n", + "print(a.size) # 5\n", + "print(a.ndim) # 1\n", + "print(a.itemsize) # 4\n", + "\n", + "b = np.array([[1, 2, 3], [4, 5, 6.0]])\n", + "print(b.shape) # (2, 3)\n", + "print(b.dtype) # float64\n", + "print(b.size) # 6\n", + "print(b.ndim) # 2\n", + "print(b.itemsize) # 8\n", + "```\n", + "\n", + "在`ndarray`中所有元素必须是同一类型,否则会自动向下转换,`int->float->str`。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 4, 5])\n", + "print(a) # [1 2 3 4 5]\n", + "b = np.array([1, 2, 3, 4, '5'])\n", + "print(b) # ['1' '2' '3' '4' '5']\n", + "c = np.array([1, 2, 3, 4, 5.0])\n", + "print(c) # [1. 2. 3. 4. 5.]\n", + "```\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "307.188px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/test.jpg b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/test.jpg new file mode 100644 index 0000000..21a22b4 Binary files /dev/null and b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/test.jpg differ diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/练习-数组的创建-答案.ipynb b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/练习-数组的创建-答案.ipynb new file mode 100644 index 0000000..bb20c3f --- /dev/null +++ b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/练习-数组的创建-答案.ipynb @@ -0,0 +1,819 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**什么是numpy?**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "numpy是python中基于数组对象的科学计算库。\n", + "提炼关键字,可以得出numpy以下三大特点:\n", + "拥有n维数组对象;\n", + "拥有广播功能(后面讲到);\n", + "拥有各种科学计算API,任你调用;" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**如何安装numpy?**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "因为numpy是一个python库,所以使用python包管理工具pip或者conda都可以安装。\n", + "安装python后,打开cmd命令行,输入:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#pip install numpy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**什么是n维数组对象?**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "n维数组(ndarray)对象,是一系列同类数据的集合,可以进行索引、切片、迭代操作。\n", + "numpy中可以使用array函数创建数组:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-04T05:37:45.921044Z", + "start_time": "2020-09-04T05:37:45.912067Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 2, 3])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np\n", + "np.array([1,2,3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**如何区分一维、二维、多维?**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "判断一个数组是几维,主要是看它有几个轴(axis)。\n", + "\n", + "一个轴表示一维数组,两个轴表示二维数组,以此类推。\n", + "\n", + "每个轴都代表一个一维数组。\n", + "\n", + "比如说,二维数组第一个轴里的每个元素都是一个一维数组,也就是第二个轴。\n", + "\n", + "一维数组一个轴:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-04T05:38:56.810220Z", + "start_time": "2020-09-04T05:38:56.807228Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2, 3]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[1,2,3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "二维数组两个轴:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-04T05:39:21.661540Z", + "start_time": "2020-09-04T05:39:21.657550Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[[0, 1, 2], [3, 4, 5]]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[[0, 1, 2],\n", + " [3, 4, 5]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "三维数组三个轴:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-04T05:39:49.201611Z", + "start_time": "2020-09-04T05:39:49.196659Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[[[ 0, 1, 2],\n", + " [ 3, 4, 5]],\n", + "\n", + " [[ 6, 7, 8],\n", + " [ 9, 10, 11]]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "以此类推n维数组。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**以下表达式运行的结果分别是什么?**\n", + "\n", + "(提示: NaN = not a number, inf = infinity)\n", + "\n", + "0 * np.nan\n", + "\n", + "np.nan == np.nan\n", + "\n", + "np.inf > np.nan\n", + "\n", + "np.nan - np.nan\n", + "\n", + "0.3 == 3 * 0.1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:29:21.779136Z", + "start_time": "2020-09-06T02:29:21.774149Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "nan\n", + "False\n", + "False\n", + "nan\n", + "False\n" + ] + } + ], + "source": [ + "print(0 * np.nan)\n", + "print(np.nan == np.nan)\n", + "print(np.inf > np.nan)\n", + "print(np.nan - np.nan)\n", + "print(0.3 == 3 * 0.1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**将numpy的datetime64对象转换为datetime的datetime对象。**\n", + "\n", + "- `dt64 = np.datetime64('2020-02-25 22:10:10')`\n", + "\n", + "【知识点:时间日期和时间增量】\n", + "- 如何将numpy的datetime64对象转换为datetime的datetime对象?" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:22:33.585786Z", + "start_time": "2020-09-06T03:22:33.577808Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2020-02-25 22:10:10 \n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import datetime\n", + "\n", + "dt64 = np.datetime64('2020-02-25 22:10:10')\n", + "dt = dt64.astype(datetime.datetime)\n", + "print(dt, type(dt))\n", + "# 2020-02-25 22:10:10 " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:23:02.362883Z", + "start_time": "2020-09-06T03:23:02.357896Z" + } + }, + "source": [ + "**给定一系列不连续的日期序列。填充缺失的日期,使其成为连续的日期序列。**\n", + "\n", + "- `dates = np.arange('2020-02-01', '2020-02-10', 2, np.datetime64)`\n", + "\n", + "【知识点:时间日期和时间增量、数学函数】\n", + "- 如何填写不规则系列的numpy日期中的缺失日期?" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:23:17.318967Z", + "start_time": "2020-09-06T03:23:17.307994Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['2020-02-01' '2020-02-03' '2020-02-05' '2020-02-07' '2020-02-09']\n", + "['2020-02-01' '2020-02-02' '2020-02-03' '2020-02-04' '2020-02-05'\n", + " '2020-02-06' '2020-02-07' '2020-02-08' '2020-02-09']\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "dates = np.arange('2020-02-01', '2020-02-10', 2, np.datetime64)\n", + "print(dates)\n", + "# ['2020-02-01' '2020-02-03' '2020-02-05' '2020-02-07' '2020-02-09']\n", + "\n", + "out = []\n", + "for date, d in zip(dates, np.diff(dates)):\n", + " out.extend(np.arange(date, date + d))\n", + "fillin = np.array(out)\n", + "output = np.hstack([fillin, dates[-1]])\n", + "print(output)\n", + "# ['2020-02-01' '2020-02-02' '2020-02-03' '2020-02-04' '2020-02-05'\n", + "# '2020-02-06' '2020-02-07' '2020-02-08' '2020-02-09']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**如何得到昨天,今天,明天的的日期**\n", + "\n", + "【知识点:时间日期】\n", + "- (提示: np.datetime64, np.timedelta64)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:21:51.819371Z", + "start_time": "2020-09-14T09:21:51.815870Z" + } + }, + "outputs": [], + "source": [ + "yesterday = np.datetime64('today', 'D') - np.timedelta64(1, 'D')\n", + "today = np.datetime64('today', 'D')\n", + "tomorrow = np.datetime64('today', 'D') + np.timedelta64(1, 'D')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:21:53.263787Z", + "start_time": "2020-09-14T09:21:53.258801Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Yesterday is 2020-09-13\n", + "Today is 2020-09-14\n", + "Tomorrow is 2020-09-15\n" + ] + } + ], + "source": [ + "print (\"Yesterday is \" + str(yesterday))\n", + "print (\"Today is \" + str(today))\n", + "print (\"Tomorrow is \"+ str(tomorrow))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "**创建从0到9的一维数字数组。**\n", + "\n", + "【知识点:数组的创建】\n", + "- 如何创建一维数组?\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-04T05:21:17.599471Z", + "start_time": "2020-09-04T05:21:17.595447Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1 2 3 4 5 6 7 8 9]\n" + ] + } + ], + "source": [ + "#【答案】\n", + "\n", + "import numpy as np\n", + "\n", + "arr = np.arange(10)\n", + "print(arr)\n", + "# [0 1 2 3 4 5 6 7 8 9]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**创建一个元素全为`True`的 3×3 数组。**\n", + "\n", + "【知识点:数组的创建】\n", + "- 如何创建一个布尔数组?" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-04T05:23:28.582218Z", + "start_time": "2020-09-04T05:23:28.578229Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ True True True]\n", + " [ True True True]\n", + " [ True True True]]\n" + ] + } + ], + "source": [ + "#答案\n", + "import numpy as np\n", + "\n", + "arr = np.full([3, 3], True, dtype=np.bool)\n", + "print(arr)\n", + "# [[ True True True]\n", + "# [ True True True]\n", + "# [ True True True]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**创建一个长度为10并且除了第五个值为1的空向量**\n", + "\n", + "【知识点:数组的创建】\n", + "\n", + "- (提示: array[4])" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-04T05:57:59.004744Z", + "start_time": "2020-09-04T05:57:58.999757Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]\n" + ] + } + ], + "source": [ + "Z = np.zeros(10)\n", + "Z[4] = 1\n", + "print(Z)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-04T05:58:20.995843Z", + "start_time": "2020-09-04T05:58:20.990855Z" + } + }, + "source": [ + "**创建一个值域范围从10到49的向量**\n", + "\n", + "【知识点:创建数组】\n", + "\n", + "- (提示: np.arange)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-04T05:58:45.316583Z", + "start_time": "2020-09-04T05:58:45.312592Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33\n", + " 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49]\n" + ] + } + ], + "source": [ + "Z = np.arange(10,50)\n", + "print(Z)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**创建一个 3x3x3的随机数组**\n", + "\n", + "【知识点:创建数组】\n", + "\n", + "(提示: np.random.random)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:25:01.890974Z", + "start_time": "2020-09-06T02:25:01.555976Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[0.9656547 0.98794518 0.97311304]\n", + " [0.70795913 0.48301228 0.99415693]\n", + " [0.88059252 0.36213986 0.09431051]]\n", + "\n", + " [[0.19983998 0.27391144 0.75292906]\n", + " [0.19717369 0.97399681 0.84519249]\n", + " [0.1990827 0.75098517 0.49597504]]\n", + "\n", + " [[0.59227295 0.13609747 0.278576 ]\n", + " [0.0652865 0.30666851 0.44145043]\n", + " [0.28980157 0.64063686 0.13204375]]]\n" + ] + } + ], + "source": [ + "Z = np.random.random((3,3,3))\n", + "print(Z)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**创建一个二维数组,其中边界值为1,其余值为0**\n", + "\n", + "【知识点:二维数组的创建】\n", + "\n", + "- (提示: array[1:-1, 1:-1])" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:26:25.019587Z", + "start_time": "2020-09-06T02:26:25.015563Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]\n", + " [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n", + " [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n", + " [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n", + " [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n", + " [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n", + " [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n", + " [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n", + " [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n", + " [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]\n" + ] + } + ], + "source": [ + "Z = np.ones((10,10))\n", + "Z[1:-1,1:-1] = 0\n", + "print(Z)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:24:54.695345Z", + "start_time": "2020-09-06T03:24:54.691389Z" + } + }, + "source": [ + "**创建长度为10的numpy数组,从5开始,在连续的数字之间的步长为3。**\n", + "\n", + "【知识点:数组的创建与属性】\n", + "- 如何在给定起始点、长度和步骤的情况下创建一个numpy数组序列?" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:25:11.711285Z", + "start_time": "2020-09-06T03:25:11.708316Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 5 8 11 14 17 20 23 26 29 32]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "start = 5\n", + "step = 3\n", + "length = 10\n", + "a = np.arange(start, start + step * length, step)\n", + "print(a) # [ 5 8 11 14 17 20 23 26 29 32]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:25:34.766852Z", + "start_time": "2020-09-06T03:25:34.762862Z" + } + }, + "source": [ + "**将本地图像导入并将其转换为numpy数组。**\n", + "\n", + "【知识点:数组的创建与属性】\n", + "- 如何将图像转换为numpy数组?" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:27:06.728838Z", + "start_time": "2020-09-06T03:27:06.496621Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(959, 959, 3) uint8\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from PIL import Image\n", + "\n", + "img1 = Image.open('test.jpg')\n", + "a = np.array(img1)\n", + "\n", + "print(a.shape, a.dtype)\n", + "# (959, 959, 3) uint8" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/练习-数组的创建.ipynb b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/练习-数组的创建.ipynb new file mode 100644 index 0000000..281b5aa --- /dev/null +++ b/IntroductionToNumpy/numpy/task01-2天-数据类型及数组创建/练习-数组的创建.ipynb @@ -0,0 +1,240 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **什么是numpy?**\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **如何安装numpy?**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **什么是n维数组对象?**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **如何区分一维、二维、多维?**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **以下表达式运行的结果分别是什么?**\n", + "\n", + "(提示: NaN = not a number, inf = infinity)\n", + "\n", + "0 * np.nan\n", + "\n", + "np.nan == np.nan\n", + "\n", + "np.inf > np.nan\n", + "\n", + "np.nan - np.nan\n", + "\n", + "0.3 == 3 * 0.1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **将numpy的datetime64对象转换为datetime的datetime对象。**\n", + "\n", + "- `dt64 = np.datetime64('2020-02-25 22:10:10')`\n", + "\n", + "【知识点:时间日期和时间增量】\n", + "- 如何将numpy的datetime64对象转换为datetime的datetime对象?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **给定一系列不连续的日期序列。填充缺失的日期,使其成为连续的日期序列。**\n", + "\n", + "- `dates = np.arange('2020-02-01', '2020-02-10', 2, np.datetime64)`\n", + "\n", + "【知识点:时间日期和时间增量、数学函数】\n", + "- 如何填写不规则系列的numpy日期中的缺失日期?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **如何得到昨天,今天,明天的的日期**\n", + "\n", + "【知识点:时间日期】\n", + "- (提示: np.datetime64, np.timedelta64)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### **创建从0到9的一维数字数组。**\n", + "\n", + "【知识点:数组的创建】\n", + "- 如何创建一维数组?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **创建一个元素全为`True`的 3×3 数组。**\n", + "\n", + "【知识点:数组的创建】\n", + "- 如何创建一个布尔数组?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **创建一个长度为10并且除了第五个值为1的空向量**\n", + "\n", + "【知识点:数组的创建】\n", + "\n", + "- (提示: array[4])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **创建一个值域范围从10到49的向量**\n", + "\n", + "【知识点:创建数组】\n", + "\n", + "- (提示: np.arange)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **创建一个 3x3x3的随机数组**\n", + "\n", + "【知识点:创建数组】\n", + "\n", + "(提示: np.random.random)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **创建一个二维数组,其中边界值为1,其余值为0**\n", + "\n", + "【知识点:二维数组的创建】\n", + "\n", + "- (提示: array[1:-1, 1:-1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **创建长度为10的numpy数组,从5开始,在连续的数字之间的步长为3。**\n", + "\n", + "【知识点:数组的创建与属性】\n", + "- 如何在给定起始点、长度和步骤的情况下创建一个numpy数组序列?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **将本地图像导入并将其转换为numpy数组。**\n", + "\n", + "【知识点:数组的创建与属性】\n", + "- 如何将图像转换为numpy数组?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task02-2天索引/.ipynb_checkpoints/练习--索引,切片迭代-checkpoint.ipynb b/IntroductionToNumpy/numpy/task02-2天索引/.ipynb_checkpoints/练习--索引,切片迭代-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/IntroductionToNumpy/numpy/task02-2天索引/.ipynb_checkpoints/练习--索引,切片迭代-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task02-2天索引/.ipynb_checkpoints/练习--索引,切片迭代-答案-checkpoint.ipynb b/IntroductionToNumpy/numpy/task02-2天索引/.ipynb_checkpoints/练习--索引,切片迭代-答案-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/IntroductionToNumpy/numpy/task02-2天索引/.ipynb_checkpoints/练习--索引,切片迭代-答案-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task02-2天索引/05. 索引、切片与迭代.ipynb b/IntroductionToNumpy/numpy/task02-2天索引/05. 索引、切片与迭代.ipynb new file mode 100644 index 0000000..349d49a --- /dev/null +++ b/IntroductionToNumpy/numpy/task02-2天索引/05. 索引、切片与迭代.ipynb @@ -0,0 +1,596 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 副本与视图\n", + "在 Numpy 中,尤其是在做数组运算或数组操作时,返回结果不是数组的 **副本** 就是 **视图**。\n", + "\n", + "在 Numpy 中,所有赋值运算不会为数组和数组中的任何元素创建副本。\n", + "\n", + "\n", + "- `numpy.ndarray.copy()` 函数创建一个副本。 对副本数据进行修改,不会影响到原始数据,它们物理内存不在同一位置。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "y = x\n", + "y[0] = -1\n", + "print(x)\n", + "# [-1 2 3 4 5 6 7 8]\n", + "print(y)\n", + "# [-1 2 3 4 5 6 7 8]\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "y = x.copy()\n", + "y[0] = -1\n", + "print(x)\n", + "# [1 2 3 4 5 6 7 8]\n", + "print(y)\n", + "# [-1 2 3 4 5 6 7 8]\n", + "```\n", + "\n", + "\n", + "\n", + "【例】数组切片操作返回的对象只是原数组的视图。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x\n", + "y[::2, :3:2] = -1\n", + "print(x)\n", + "# [[-1 12 -1 14 15]\n", + "# [16 17 18 19 20]\n", + "# [-1 22 -1 24 25]\n", + "# [26 27 28 29 30]\n", + "# [-1 32 -1 34 35]]\n", + "print(y)\n", + "# [[-1 12 -1 14 15]\n", + "# [16 17 18 19 20]\n", + "# [-1 22 -1 24 25]\n", + "# [26 27 28 29 30]\n", + "# [-1 32 -1 34 35]]\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x.copy()\n", + "y[::2, :3:2] = -1\n", + "print(x)\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "print(y)\n", + "# [[-1 12 -1 14 15]\n", + "# [16 17 18 19 20]\n", + "# [-1 22 -1 24 25]\n", + "# [26 27 28 29 30]\n", + "# [-1 32 -1 34 35]]\n", + "```\n", + "\n", + "\n", + "# 索引与切片\n", + "\n", + "数组索引机制指的是用方括号([])加序号的形式引用单个数组元素,它的用处很多,比如抽取元素,选取数组的几个元素,甚至为其赋一个新值。\n", + "\n", + "## 整数索引\n", + "\n", + "【例】要获取数组的单个元素,指定元素的索引即可。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "print(x[2]) # 3\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "print(x[2]) # [21 22 23 24 25]\n", + "print(x[2][1]) # 22\n", + "print(x[2, 1]) # 22\n", + "```\n", + "\n", + "## 切片索引\n", + "\n", + "切片操作是指抽取数组的一部分元素生成新数组。对 python **列表**进行切片操作得到的数组是原数组的**副本**,而对 **Numpy** 数据进行切片操作得到的数组则是指向相同缓冲区的**视图**。\n", + "\n", + "\n", + "如果想抽取(或查看)数组的一部分,必须使用切片语法,也就是,把几个用冒号( `start:stop:step` )隔开的数字置于方括号内。\n", + "\n", + "为了更好地理解切片语法,还应该了解不明确指明起始和结束位置的情况。如省去第一个数字,numpy 会认为第一个数字是0;如省去第二个数字,numpy 则会认为第二个数字是数组的最大索引值;如省去最后一个数字,它将会被理解为1,也就是抽取所有元素而不再考虑间隔。\n", + "\n", + "\n", + "【例】对一维数组的切片\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "print(x[0:2]) # [1 2]\n", + "print(x[1:5:2]) # [2 4]\n", + "print(x[2:]) # [3 4 5 6 7 8]\n", + "print(x[:2]) # [1 2]\n", + "print(x[-2:]) # [7 8]\n", + "print(x[:-2]) # [1 2 3 4 5 6]\n", + "print(x[:]) # [1 2 3 4 5 6 7 8]\n", + "print(x[::-1]) # [8 7 6 5 4 3 2 1]\n", + "```\n", + "\n", + "【例】对二维数组切片\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "print(x[0:2])\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]]\n", + "\n", + "print(x[1:5:2])\n", + "# [[16 17 18 19 20]\n", + "# [26 27 28 29 30]]\n", + "\n", + "print(x[2:])\n", + "# [[21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "\n", + "print(x[:2])\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]]\n", + "\n", + "print(x[-2:])\n", + "# [[26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "\n", + "print(x[:-2])\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]]\n", + "\n", + "print(x[:])\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "\n", + "print(x[2, :]) # [21 22 23 24 25]\n", + "print(x[:, 2]) # [13 18 23 28 33]\n", + "print(x[0, 1:4]) # [12 13 14]\n", + "print(x[1:4, 0]) # [16 21 26]\n", + "print(x[1:3, 2:4])\n", + "# [[18 19]\n", + "# [23 24]]\n", + "\n", + "print(x[:, :])\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "\n", + "print(x[::2, ::2])\n", + "# [[11 13 15]\n", + "# [21 23 25]\n", + "# [31 33 35]]\n", + "\n", + "print(x[::-1, :])\n", + "# [[31 32 33 34 35]\n", + "# [26 27 28 29 30]\n", + "# [21 22 23 24 25]\n", + "# [16 17 18 19 20]\n", + "# [11 12 13 14 15]]\n", + "\n", + "print(x[:, ::-1])\n", + "# [[15 14 13 12 11]\n", + "# [20 19 18 17 16]\n", + "# [25 24 23 22 21]\n", + "# [30 29 28 27 26]\n", + "# [35 34 33 32 31]]\n", + "```\n", + "\n", + "\n", + "通过对每个以逗号分隔的维度执行单独的切片,你可以对多维数组进行切片。因此,对于二维数组,我们的第一片定义了行的切片,第二片定义了列的切片。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "print(x)\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "\n", + "x[0::2, 1::3] = 0\n", + "print(x)\n", + "# [[11 0 13 14 0]\n", + "# [16 17 18 19 20]\n", + "# [21 0 23 24 0]\n", + "# [26 27 28 29 30]\n", + "# [31 0 33 34 0]]\n", + "```\n", + "\n", + "## dots 索引\n", + "\n", + "NumPy 允许使用`...`表示足够多的冒号来构建完整的索引列表。\n", + "\n", + "比如,如果 `x` 是 5 维数组:\n", + "\n", + "- `x[1,2,...]` 等于 `x[1,2,:,:,:]`\n", + "- `x[...,3]` 等于 `x[:,:,:,:,3]` \n", + "- `x[4,...,5,:]` 等于 `x[4,:,:,5,:]`\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.random.randint(1, 100, [2, 2, 3])\n", + "print(x)\n", + "# [[[ 5 64 75]\n", + "# [57 27 31]]\n", + "# \n", + "# [[68 85 3]\n", + "# [93 26 25]]]\n", + "\n", + "print(x[1, ...])\n", + "# [[68 85 3]\n", + "# [93 26 25]]\n", + "\n", + "print(x[..., 2])\n", + "# [[75 31]\n", + "# [ 3 25]]\n", + "```\n", + "\n", + "\n", + "\n", + "## 整数数组索引\n", + "\n", + "【例】方括号内传入多个索引值,可以同时选择多个元素。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "r = [0, 1, 2]\n", + "print(x[r])\n", + "# [1 2 3]\n", + "\n", + "r = [0, 1, -1]\n", + "print(x[r])\n", + "# [1 2 8]\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "r = [0, 1, 2]\n", + "print(x[r])\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]]\n", + "\n", + "r = [0, 1, -1]\n", + "print(x[r])\n", + "\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [31 32 33 34 35]]\n", + "\n", + "r = [0, 1, 2]\n", + "c = [2, 3, 4]\n", + "y = x[r, c]\n", + "print(y)\n", + "# [13 19 25]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "r = np.array([[0, 1], [3, 4]])\n", + "print(x[r])\n", + "# [[1 2]\n", + "# [4 5]]\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "r = np.array([[0, 1], [3, 4]])\n", + "print(x[r])\n", + "# [[[11 12 13 14 15]\n", + "# [16 17 18 19 20]]\n", + "#\n", + "# [[26 27 28 29 30]\n", + "# [31 32 33 34 35]]]\n", + "\n", + "# 获取了 5X5 数组中的四个角的元素。\n", + "# 行索引是 [0,0] 和 [4,4],而列索引是 [0,4] 和 [0,4]。\n", + "r = np.array([[0, 0], [4, 4]])\n", + "c = np.array([[0, 4], [0, 4]])\n", + "y = x[r, c]\n", + "print(y)\n", + "# [[11 15]\n", + "# [31 35]]\n", + "```\n", + "\n", + "【例】可以借助切片`:`与整数数组组合。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = x[0:3, [1, 2, 2]]\n", + "print(y)\n", + "# [[12 13 13]\n", + "# [17 18 18]\n", + "# [22 23 23]]\n", + "```\n", + "\n", + "- `numpy. take(a, indices, axis=None, out=None, mode='raise')` Take elements from an array along an axis.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "r = [0, 1, 2]\n", + "print(np.take(x, r))\n", + "# [1 2 3]\n", + "\n", + "r = [0, 1, -1]\n", + "print(np.take(x, r))\n", + "# [1 2 8]\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "r = [0, 1, 2]\n", + "print(np.take(x, r, axis=0))\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]]\n", + "\n", + "r = [0, 1, -1]\n", + "print(np.take(x, r, axis=0))\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [31 32 33 34 35]]\n", + "\n", + "r = [0, 1, 2]\n", + "c = [2, 3, 4]\n", + "y = np.take(x, [r, c])\n", + "print(y)\n", + "# [[11 12 13]\n", + "# [13 14 15]]\n", + "```\n", + "\n", + "\n", + "## 布尔索引\n", + "\n", + "我们可以通过一个布尔数组来索引目标数组。\n", + "\n", + "【例】\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "y = x > 5\n", + "print(y)\n", + "# [False False False False False True True True]\n", + "print(x[x > 5])\n", + "# [6 7 8]\n", + "\n", + "x = np.array([np.nan, 1, 2, np.nan, 3, 4, 5])\n", + "y = np.logical_not(np.isnan(x))\n", + "print(x[y])\n", + "# [1. 2. 3. 4. 5.]\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x > 25\n", + "print(y)\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [ True True True True True]\n", + "# [ True True True True True]]\n", + "print(x[x > 25])\n", + "# [26 27 28 29 30 31 32 33 34 35]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "x = np.linspace(0, 2 * np.pi, 50)\n", + "y = np.sin(x)\n", + "print(len(x)) # 50\n", + "plt.plot(x, y)\n", + "\n", + "mask = y >= 0\n", + "print(len(x[mask])) # 25\n", + "print(mask)\n", + "'''\n", + "[ True True True True True True True True True True True True\n", + " True True True True True True True True True True True True\n", + " True False False False False False False False False False False False\n", + " False False False False False False False False False False False False\n", + " False False]\n", + "'''\n", + "plt.plot(x[mask], y[mask], 'bo')\n", + "\n", + "mask = np.logical_and(y >= 0, x <= np.pi / 2)\n", + "print(mask)\n", + "'''\n", + "[ True True True True True True True True True True True True\n", + " True False False False False False False False False False False False\n", + " False False False False False False False False False False False False\n", + " False False False False False False False False False False False False\n", + " False False]\n", + "'''\n", + "\n", + "plt.plot(x[mask], y[mask], 'go')\n", + "plt.show()\n", + "```\n", + "\n", + "![](https://img-blog.csdnimg.cn/20191109183704335.png)\n", + "\n", + "我们利用这些条件来选择图上的不同点。蓝色点(在图中还包括绿点,但绿点掩盖了蓝色点),显示值 大于0 的所有点。绿色点表示值 大于0 且 小于0.5π 的所有点。\n", + "\n", + "\n", + "\n", + "\n", + "---\n", + "# 数组迭代\n", + "\n", + "除了for循环,Numpy 还提供另外一种更为优雅的遍历方法。\n", + "\n", + "- `apply_along_axis(func1d, axis, arr)` Apply a function to 1-D slices along the given axis.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = np.apply_along_axis(np.sum, 0, x)\n", + "print(y) # [105 110 115 120 125]\n", + "y = np.apply_along_axis(np.sum, 1, x)\n", + "print(y) # [ 65 90 115 140 165]\n", + "\n", + "y = np.apply_along_axis(np.mean, 0, x)\n", + "print(y) # [21. 22. 23. 24. 25.]\n", + "y = np.apply_along_axis(np.mean, 1, x)\n", + "print(y) # [13. 18. 23. 28. 33.]\n", + "\n", + "\n", + "def my_func(x):\n", + " return (x[0] + x[-1]) * 0.5\n", + "\n", + "\n", + "y = np.apply_along_axis(my_func, 0, x)\n", + "print(y) # [21. 22. 23. 24. 25.]\n", + "y = np.apply_along_axis(my_func, 1, x)\n", + "print(y) # [13. 18. 23. 28. 33.]\n", + "```\n", + "\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "307.2px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task02-2天索引/练习--索引,切片迭代-答案.ipynb b/IntroductionToNumpy/numpy/task02-2天索引/练习--索引,切片迭代-答案.ipynb new file mode 100644 index 0000000..c24795c --- /dev/null +++ b/IntroductionToNumpy/numpy/task02-2天索引/练习--索引,切片迭代-答案.ipynb @@ -0,0 +1,291 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**交换数组arr中的列1和列2。**\n", + "\n", + "- `arr = np.arange(9).reshape(3, 3)`\n", + "\n", + "【知识点:索引与切片】\n", + "- 如何交换二维数组中的两列?" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:56:51.266868Z", + "start_time": "2020-09-06T02:56:51.260884Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2]\n", + " [3 4 5]\n", + " [6 7 8]]\n", + "[[2 1 0]\n", + " [5 4 3]\n", + " [8 7 6]]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "arr = np.arange(9).reshape(3, 3)\n", + "print(arr)\n", + "# [[0 1 2]\n", + "# [3 4 5]\n", + "# [6 7 8]]\n", + "\n", + "x = arr[:, [2, 1, 0]]\n", + "print(x)\n", + "# [[2 1 0]\n", + "# [5 4 3]\n", + "# [8 7 6]]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:57:26.869431Z", + "start_time": "2020-09-06T02:57:26.864408Z" + } + }, + "source": [ + "**交换数组arr中的第1行和第2行。**\n", + "- `arr = np.arange(9).reshape(3, 3)`\n", + "\n", + "【知识点:索引与切片】\n", + "- 如何交换二维数组中的两行?" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:57:43.336029Z", + "start_time": "2020-09-06T02:57:43.331042Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2]\n", + " [3 4 5]\n", + " [6 7 8]]\n", + "[[3 4 5]\n", + " [0 1 2]\n", + " [6 7 8]]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "arr = np.arange(9).reshape(3, 3)\n", + "print(arr)\n", + "# [[0 1 2]\n", + "# [3 4 5]\n", + "# [6 7 8]]\n", + "\n", + "x = arr[[1, 0, 2], :]\n", + "print(x)\n", + "# [[3 4 5]\n", + "# [0 1 2]\n", + "# [6 7 8]]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:58:04.059418Z", + "start_time": "2020-09-06T02:58:04.054430Z" + } + }, + "source": [ + "**反转二维数组arr的行。**\n", + "\n", + "- `arr = np.arange(9).reshape(3, 3)`\n", + "\n", + "【知识点:索引与切片】\n", + "- 如何反转二维数组的行?" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:58:21.071694Z", + "start_time": "2020-09-06T02:58:21.067682Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2]\n", + " [3 4 5]\n", + " [6 7 8]]\n", + "[[6 7 8]\n", + " [3 4 5]\n", + " [0 1 2]]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "arr = np.arange(9).reshape(3, 3)\n", + "print(arr)\n", + "# [[0 1 2]\n", + "# [3 4 5]\n", + "# [6 7 8]]\n", + "\n", + "x = arr[::-1, :]\n", + "print(x)\n", + "# [[6 7 8]\n", + "# [3 4 5]\n", + "# [0 1 2]]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:58:39.880250Z", + "start_time": "2020-09-06T02:58:39.875230Z" + } + }, + "source": [ + "**反转二维数组arr的列。**\n", + "- `arr = np.arange(9).reshape(3, 3)`\n", + "\n", + "【知识点:索引与切片】\n", + "- 如何反转二维数组的列?" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:58:54.851622Z", + "start_time": "2020-09-06T02:58:54.846601Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2]\n", + " [3 4 5]\n", + " [6 7 8]]\n", + "[[2 1 0]\n", + " [5 4 3]\n", + " [8 7 6]]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "arr = np.arange(9).reshape(3, 3)\n", + "print(arr)\n", + "# [[0 1 2]\n", + "# [3 4 5]\n", + "# [6 7 8]]\n", + "\n", + "x = arr[:, ::-1]\n", + "print(x)\n", + "# [[2 1 0]\n", + "# [5 4 3]\n", + "# [8 7 6]]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task02-2天索引/练习--索引,切片迭代.ipynb b/IntroductionToNumpy/numpy/task02-2天索引/练习--索引,切片迭代.ipynb new file mode 100644 index 0000000..2da4fa2 --- /dev/null +++ b/IntroductionToNumpy/numpy/task02-2天索引/练习--索引,切片迭代.ipynb @@ -0,0 +1,120 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **交换数组arr中的列1和列2。**\n", + "\n", + "- `arr = np.arange(9).reshape(3, 3)`\n", + "\n", + "【知识点:索引与切片】\n", + "- 如何交换二维数组中的两列?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **交换数组arr中的第1行和第2行。**\n", + "- `arr = np.arange(9).reshape(3, 3)`\n", + "\n", + "【知识点:索引与切片】\n", + "- 如何交换二维数组中的两行?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **反转二维数组arr的行。**\n", + "\n", + "- `arr = np.arange(9).reshape(3, 3)`\n", + "\n", + "【知识点:索引与切片】\n", + "- 如何反转二维数组的行?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **反转二维数组arr的列。**\n", + "- `arr = np.arange(9).reshape(3, 3)`\n", + "\n", + "【知识点:索引与切片】\n", + "- 如何反转二维数组的列?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/.ipynb_checkpoints/06. 数组操作-checkpoint.ipynb b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/.ipynb_checkpoints/06. 数组操作-checkpoint.ipynb new file mode 100644 index 0000000..d149a43 --- /dev/null +++ b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/.ipynb_checkpoints/06. 数组操作-checkpoint.ipynb @@ -0,0 +1,940 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 数组操作\n", + "\n", + "## 更改形状\n", + "\n", + "在对数组进行操作时,为了满足格式和计算的要求通常会改变其形状。\n", + "\n", + "- `numpy.ndarray.shape`表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 `ndim` 属性(秩)。\n", + "\n", + "【例】通过修改 shap 属性来改变数组的形状。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 9, 4, 5, 6, 7, 8])\n", + "print(x.shape) # (8,)\n", + "x.shape = [2, 4]\n", + "print(x)\n", + "# [[1 2 9 4]\n", + "# [5 6 7 8]]\n", + "```\n", + "\n", + "- `numpy.ndarray.flat` 将数组转换为一维的迭代器,可以用for访问数组每一个元素。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x.flat\n", + "print(y)\n", + "# \n", + "for i in y:\n", + " print(i, end=' ')\n", + "# 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35\n", + "\n", + "y[3] = 0\n", + "print(end='\\n')\n", + "print(x)\n", + "# [[11 12 13 0 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "```\n", + "\n", + "- `numpy.ndarray.flatten([order='C'])` 将数组的副本转换为一维数组,并返回。\n", + " - order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序。(简记)\n", + " - order:{'C / F,'A,K},可选使用此索引顺序读取a的元素。'C'意味着以行大的C风格顺序对元素进行索引,最后一个轴索引会更改F表示以列大的Fortran样式顺序索引元素,其中第一个索引变化最快,最后一个索引变化最快。请注意,'C'和'F'选项不考虑基础数组的内存布局,仅引用轴索引的顺序.A'表示如果a为Fortran,则以类似Fortran的索引顺序读取元素在内存中连续,否则类似C的顺序。“ K”表示按照步序在内存中的顺序读取元素,但步幅为负时反转数据除外。默认情况下,使用Cindex顺序。\n", + "\n", + "【例】`flatten()`函数返回的是拷贝。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x.flatten()\n", + "print(y)\n", + "# [11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34\n", + "# 35]\n", + "\n", + "y[3] = 0\n", + "print(x)\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = x.flatten(order='F')\n", + "print(y)\n", + "# [11 16 21 26 31 12 17 22 27 32 13 18 23 28 33 14 19 24 29 34 15 20 25 30\n", + "# 35]\n", + "\n", + "y[3] = 0\n", + "print(x)\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "```\n", + "\n", + "\n", + "\n", + "- `numpy.ravel(a, order='C')`Return a contiguous flattened array.\n", + "\n", + "【例】`ravel()`返回的是视图。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.ravel(x)\n", + "print(y)\n", + "# [11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34\n", + "# 35]\n", + "\n", + "y[3] = 0\n", + "print(x)\n", + "# [[11 12 13 0 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "\n", + "【例】order=F 就是拷贝\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = np.ravel(x, order='F')\n", + "print(y)\n", + "# [11 16 21 26 31 12 17 22 27 32 13 18 23 28 33 14 19 24 29 34 15 20 25 30\n", + "# 35]\n", + "\n", + "y[3] = 0\n", + "print(x)\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "```\n", + "\n", + "- `numpy.reshape(a, newshape[, order='C'])`在不更改数据的情况下为数组赋予新的形状。\n", + "\n", + "【例】`reshape()`函数当参数`newshape = [rows,-1]`时,将根据行数自动确定列数。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(12)\n", + "y = np.reshape(x, [3, 4])\n", + "print(y.dtype) # int32\n", + "print(y)\n", + "# [[ 0 1 2 3]\n", + "# [ 4 5 6 7]\n", + "# [ 8 9 10 11]]\n", + "\n", + "y = np.reshape(x, [3, -1])\n", + "print(y)\n", + "# [[ 0 1 2 3]\n", + "# [ 4 5 6 7]\n", + "# [ 8 9 10 11]]\n", + "\n", + "y = np.reshape(x,[-1,3])\n", + "print(y)\n", + "# [[ 0 1 2]\n", + "# [ 3 4 5]\n", + "# [ 6 7 8]\n", + "# [ 9 10 11]]\n", + "\n", + "y[0, 1] = 10\n", + "print(x)\n", + "# [ 0 10 2 3 4 5 6 7 8 9 10 11](改变x去reshape后y中的值,x对应元素也改变)\n", + "```\n", + "\n", + "【例】`reshape()`函数当参数`newshape = -1`时,表示将数组降为一维。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.random.randint(12, size=[2, 2, 3])\n", + "print(x)\n", + "# [[[11 9 1]\n", + "# [ 1 10 3]]\n", + "# \n", + "# [[ 0 6 1]\n", + "# [ 4 11 3]]]\n", + "y = np.reshape(x, -1)\n", + "print(y)\n", + "# [11 9 1 1 10 3 0 6 1 4 11 3]\n", + "```\n", + "\n", + "\n", + "\n", + "## 数组转置\n", + "\n", + "\n", + "- `numpy.transpose(a, axes=None)` Permute the dimensions of an array.\n", + "- `numpy.ndarray.T` Same as `self.transpose()`, except that self is returned if `self.ndim < 2`.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.random.rand(5, 5) * 10\n", + "x = np.around(x, 2)\n", + "print(x)\n", + "# [[6.74 8.46 6.74 5.45 1.25]\n", + "# [3.54 3.49 8.62 1.94 9.92]\n", + "# [5.03 7.22 1.6 8.7 0.43]\n", + "# [7.5 7.31 5.69 9.67 7.65]\n", + "# [1.8 9.52 2.78 5.87 4.14]]\n", + "y = x.T\n", + "print(y)\n", + "# [[6.74 3.54 5.03 7.5 1.8 ]\n", + "# [8.46 3.49 7.22 7.31 9.52]\n", + "# [6.74 8.62 1.6 5.69 2.78]\n", + "# [5.45 1.94 8.7 9.67 5.87]\n", + "# [1.25 9.92 0.43 7.65 4.14]]\n", + "y = np.transpose(x)\n", + "print(y)\n", + "# [[6.74 3.54 5.03 7.5 1.8 ]\n", + "# [8.46 3.49 7.22 7.31 9.52]\n", + "# [6.74 8.62 1.6 5.69 2.78]\n", + "# [5.45 1.94 8.7 9.67 5.87]\n", + "# [1.25 9.92 0.43 7.65 4.14]]\n", + "```\n", + "\n", + "\n", + "## 更改维度\n", + "\n", + "当创建一个数组之后,还可以给它增加一个维度,这在矩阵计算中经常会用到。\n", + "\n", + "- `numpy.newaxis = None` `None`的别名,对索引数组很有用。\n", + "\n", + "【例】很多工具包在进行计算时都会先判断输入数据的维度是否满足要求,如果输入数据达不到指定的维度时,可以使用`newaxis`参数来增加一个维度。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 9, 4, 5, 6, 7, 8])\n", + "print(x.shape) # (8,)\n", + "print(x) # [1 2 9 4 5 6 7 8]\n", + "\n", + "y = x[np.newaxis, :]\n", + "print(y.shape) # (1, 8)\n", + "print(y) # [[1 2 9 4 5 6 7 8]]\n", + "\n", + "y = x[:, np.newaxis]\n", + "print(y.shape) # (8, 1)\n", + "print(y)\n", + "# [[1]\n", + "# [2]\n", + "# [9]\n", + "# [4]\n", + "# [5]\n", + "# [6]\n", + "# [7]\n", + "# [8]]\n", + "```\n", + "\n", + "- `numpy.squeeze(a, axis=None)` 从数组的形状中删除单维度条目,即把shape中为1的维度去掉。\n", + " - `a`表示输入的数组;\n", + " - `axis`用于指定需要删除的维度,但是指定的维度必须为单维度,否则将会报错;\n", + "\n", + "在机器学习和深度学习中,通常算法的结果是可以表示向量的数组(即包含两对或以上的方括号形式[[]]),如果直接利用这个数组进行画图可能显示界面为空(见后面的示例)。我们可以利用`squeeze()`函数将表示向量的数组转换为秩为1的数组,这样利用 matplotlib 库函数画图时,就可以正常的显示结果了。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(10)\n", + "print(x.shape) # (10,)\n", + "x = x[np.newaxis, :]\n", + "print(x.shape) # (1, 10)\n", + "y = np.squeeze(x)\n", + "print(y.shape) # (10,)\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[[0], [1], [2]]])\n", + "print(x.shape) # (1, 3, 1)\n", + "print(x)\n", + "# [[[0]\n", + "# [1]\n", + "# [2]]]\n", + "\n", + "y = np.squeeze(x)\n", + "print(y.shape) # (3,)\n", + "print(y) # [0 1 2]\n", + "\n", + "y = np.squeeze(x, axis=0)\n", + "print(y.shape) # (3, 1)\n", + "print(y)\n", + "# [[0]\n", + "# [1]\n", + "# [2]]\n", + "\n", + "y = np.squeeze(x, axis=2)\n", + "print(y.shape) # (1, 3)\n", + "print(y) # [[0 1 2]]\n", + "\n", + "y = np.squeeze(x, axis=1)\n", + "# ValueError: cannot select an axis to squeeze out which has size not equal to one\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "x = np.array([[1, 4, 9, 16, 25]])\n", + "print(x.shape) # (1, 5)\n", + "plt.plot(x)\n", + "plt.show()\n", + "```\n", + "![](https://img-blog.csdnimg.cn/20200528095957317.png)\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "x = np.array([[1, 4, 9, 16, 25]])\n", + "x = np.squeeze(x)\n", + "print(x.shape) # (5, )\n", + "plt.plot(x)\n", + "plt.show()\n", + "```\n", + "\n", + "![](https://img-blog.csdnimg.cn/20200528100221464.png)\n", + "\n", + "## 数组组合\n", + "\n", + "如果要将两份数据组合到一起,就需要拼接操作。\n", + "\n", + "- `numpy.concatenate((a1, a2, ...), axis=0, out=None)` Join a sequence of arrays along an existing axis.\n", + "\n", + "【例】连接沿现有轴的数组序列(原来x,y都是一维的,拼接后的结果也是一维的)。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3])\n", + "y = np.array([7, 8, 9])\n", + "z = np.concatenate([x, y])\n", + "print(z)\n", + "# [1 2 3 7 8 9]\n", + "\n", + "z = np.concatenate([x, y], axis=0)\n", + "print(z)\n", + "# [1 2 3 7 8 9]\n", + "```\n", + "\n", + "【例】原来x,y都是二维的,拼接后的结果也是二维的。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3]).reshape(1, 3)\n", + "y = np.array([7, 8, 9]).reshape(1, 3)\n", + "z = np.concatenate([x, y])\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 7 8 9]]\n", + "z = np.concatenate([x, y], axis=0)\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 7 8 9]]\n", + "z = np.concatenate([x, y], axis=1)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]]\n", + "```\n", + "\n", + "【例】x,y在原来的维度上进行拼接。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.array([[7, 8, 9], [10, 11, 12]])\n", + "z = np.concatenate([x, y])\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 4 5 6]\n", + "# [ 7 8 9]\n", + "# [10 11 12]]\n", + "z = np.concatenate([x, y], axis=0)\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 4 5 6]\n", + "# [ 7 8 9]\n", + "# [10 11 12]]\n", + "z = np.concatenate([x, y], axis=1)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]\n", + "# [ 4 5 6 10 11 12]]\n", + "```\n", + "\n", + "- `numpy.stack(arrays, axis=0, out=None)`Join a sequence of arrays along a new axis.\n", + "\n", + "\n", + "【例】沿着新的轴加入一系列数组(stack为增加维度的拼接)。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3])\n", + "y = np.array([7, 8, 9])\n", + "z = np.stack([x, y])\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.stack([x, y], axis=1)\n", + "print(z.shape) # (3, 2)\n", + "print(z)\n", + "# [[1 7]\n", + "# [2 8]\n", + "# [3 9]]\n", + "```\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3]).reshape(1, 3)\n", + "y = np.array([7, 8, 9]).reshape(1, 3)\n", + "z = np.stack([x, y])\n", + "print(z.shape) # (2, 1, 3)\n", + "print(z)\n", + "# [[[1 2 3]]\n", + "#\n", + "# [[7 8 9]]]\n", + "\n", + "z = np.stack([x, y], axis=1)\n", + "print(z.shape) # (1, 2, 3)\n", + "print(z)\n", + "# [[[1 2 3]\n", + "# [7 8 9]]]\n", + "\n", + "z = np.stack([x, y], axis=2)\n", + "print(z.shape) # (1, 3, 2)\n", + "print(z)\n", + "# [[[1 7]\n", + "# [2 8]\n", + "# [3 9]]]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.array([[7, 8, 9], [10, 11, 12]])\n", + "z = np.stack([x, y])\n", + "print(z.shape) # (2, 2, 3)\n", + "print(z)\n", + "# [[[ 1 2 3]\n", + "# [ 4 5 6]]\n", + "# \n", + "# [[ 7 8 9]\n", + "# [10 11 12]]]\n", + "\n", + "z = np.stack([x, y], axis=1)\n", + "print(z.shape) # (2, 2, 3)\n", + "print(z)\n", + "# [[[ 1 2 3]\n", + "# [ 7 8 9]]\n", + "# \n", + "# [[ 4 5 6]\n", + "# [10 11 12]]]\n", + "\n", + "z = np.stack([x, y], axis=2)\n", + "print(z.shape) # (2, 3, 2)\n", + "print(z)\n", + "# [[[ 1 7]\n", + "# [ 2 8]\n", + "# [ 3 9]]\n", + "# \n", + "# [[ 4 10]\n", + "# [ 5 11]\n", + "# [ 6 12]]]\n", + "```\n", + "\n", + "\n", + "- `numpy.vstack(tup)`Stack arrays in sequence vertically (row wise).\n", + "- `numpy.hstack(tup)`Stack arrays in sequence horizontally (column wise). \n", + "\n", + "\n", + "【例】一维的情况。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3])\n", + "y = np.array([7, 8, 9])\n", + "z = np.vstack((x, y))\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.stack([x, y])\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.hstack((x, y))\n", + "print(z.shape) # (6,)\n", + "print(z)\n", + "# [1 2 3 7 8 9]\n", + "\n", + "z = np.concatenate((x, y))\n", + "print(z.shape) # (6,)\n", + "print(z) # [1 2 3 7 8 9]\n", + "```\n", + "\n", + "\n", + "\n", + "【例】二维的情况。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3]).reshape(1, 3)\n", + "y = np.array([7, 8, 9]).reshape(1, 3)\n", + "z = np.vstack((x, y))\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.concatenate((x, y), axis=0)\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.hstack((x, y))\n", + "print(z.shape) # (1, 6)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]]\n", + "\n", + "z = np.concatenate((x, y), axis=1)\n", + "print(z.shape) # (1, 6)\n", + "print(z)\n", + "# [[1 2 3 7 8 9]]\n", + "```\n", + "\n", + "【例】二维的情况。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.array([[7, 8, 9], [10, 11, 12]])\n", + "z = np.vstack((x, y))\n", + "print(z.shape) # (4, 3)\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 4 5 6]\n", + "# [ 7 8 9]\n", + "# [10 11 12]]\n", + "\n", + "z = np.concatenate((x, y), axis=0)\n", + "print(z.shape) # (4, 3)\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 4 5 6]\n", + "# [ 7 8 9]\n", + "# [10 11 12]]\n", + "\n", + "z = np.hstack((x, y))\n", + "print(z.shape) # (2, 6)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]\n", + "# [ 4 5 6 10 11 12]]\n", + "\n", + "z = np.concatenate((x, y), axis=1)\n", + "print(z.shape) # (2, 6)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]\n", + "# [ 4 5 6 10 11 12]]\n", + "```\n", + "\n", + "`hstack(),vstack()`分别表示水平和竖直的拼接方式。在数据维度等于1时,比较特殊。而当维度大于或等于2时,它们的作用相当于`concatenate`,用于在已有轴上进行操作。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.hstack([np.array([1, 2, 3, 4]), 5])\n", + "print(a) # [1 2 3 4 5]\n", + "\n", + "a = np.concatenate([np.array([1, 2, 3, 4]), 5])\n", + "print(a)\n", + "# all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 0 dimension(s)\n", + "```\n", + "\n", + "\n", + "## 数组拆分\n", + "\n", + "- `numpy.split(ary, indices_or_sections, axis=0)` Split an array into multiple sub-arrays as views into ary.\n", + "\n", + "【例】拆分数组。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14],\n", + " [16, 17, 18, 19],\n", + " [21, 22, 23, 24]])\n", + "y = np.split(x, [1, 3])\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]]), array([], shape=(0, 4), dtype=int32)]\n", + "\n", + "y = np.split(x, [1, 3], axis=1)\n", + "print(y)\n", + "# [array([[11],\n", + "# [16],\n", + "# [21]]), array([[12, 13],\n", + "# [17, 18],\n", + "# [22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "```\n", + "\n", + "\n", + "\n", + "- `numpy.vsplit(ary, indices_or_sections)` Split an array into multiple sub-arrays vertically (row-wise).\n", + "\n", + "【例】垂直切分是把数组按照高度切分\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14],\n", + " [16, 17, 18, 19],\n", + " [21, 22, 23, 24]])\n", + "y = np.vsplit(x, 3)\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19]]), array([[21, 22, 23, 24]])]\n", + "\n", + "y = np.split(x, 3)\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19]]), array([[21, 22, 23, 24]])]\n", + "\n", + "\n", + "y = np.vsplit(x, [1])\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]])]\n", + "\n", + "y = np.split(x, [1])\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]])]\n", + "\n", + "\n", + "y = np.vsplit(x, [1, 3])\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]]), array([], shape=(0, 4), dtype=int32)]\n", + "y = np.split(x, [1, 3], axis=0)\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]]), array([], shape=(0, 4), dtype=int32)]\n", + "```\n", + "\n", + "- `numpy.hsplit(ary, indices_or_sections)` Split an array into multiple sub-arrays horizontally (column-wise).\n", + "\n", + "\n", + "【例】水平切分是把数组按照宽度切分。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14],\n", + " [16, 17, 18, 19],\n", + " [21, 22, 23, 24]])\n", + "y = np.hsplit(x, 2)\n", + "print(y)\n", + "# [array([[11, 12],\n", + "# [16, 17],\n", + "# [21, 22]]), array([[13, 14],\n", + "# [18, 19],\n", + "# [23, 24]])]\n", + "\n", + "y = np.split(x, 2, axis=1)\n", + "print(y)\n", + "# [array([[11, 12],\n", + "# [16, 17],\n", + "# [21, 22]]), array([[13, 14],\n", + "# [18, 19],\n", + "# [23, 24]])]\n", + "\n", + "y = np.hsplit(x, [3])\n", + "print(y)\n", + "# [array([[11, 12, 13],\n", + "# [16, 17, 18],\n", + "# [21, 22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "\n", + "y = np.split(x, [3], axis=1)\n", + "print(y)\n", + "# [array([[11, 12, 13],\n", + "# [16, 17, 18],\n", + "# [21, 22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "\n", + "y = np.hsplit(x, [1, 3])\n", + "print(y)\n", + "# [array([[11],\n", + "# [16],\n", + "# [21]]), array([[12, 13],\n", + "# [17, 18],\n", + "# [22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "\n", + "y = np.split(x, [1, 3], axis=1)\n", + "print(y)\n", + "# [array([[11],\n", + "# [16],\n", + "# [21]]), array([[12, 13],\n", + "# [17, 18],\n", + "# [22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "## 数组平铺\n", + "\n", + "- `numpy.tile(A, reps)` Construct an array by repeating A the number of times given by reps.\n", + "\n", + "`tile`是瓷砖的意思,顾名思义,这个函数就是把数组像瓷砖一样铺展开来。\n", + "\n", + "【例】将原矩阵横向、纵向地复制。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2], [3, 4]])\n", + "print(x)\n", + "# [[1 2]\n", + "# [3 4]]\n", + "\n", + "y = np.tile(x, (1, 3))\n", + "print(y)\n", + "# [[1 2 1 2 1 2]\n", + "# [3 4 3 4 3 4]]\n", + "\n", + "y = np.tile(x, (3, 1))\n", + "print(y)\n", + "# [[1 2]\n", + "# [3 4]\n", + "# [1 2]\n", + "# [3 4]\n", + "# [1 2]\n", + "# [3 4]]\n", + "\n", + "y = np.tile(x, (3, 3))\n", + "print(y)\n", + "# [[1 2 1 2 1 2]\n", + "# [3 4 3 4 3 4]\n", + "# [1 2 1 2 1 2]\n", + "# [3 4 3 4 3 4]\n", + "# [1 2 1 2 1 2]\n", + "# [3 4 3 4 3 4]]\n", + "```\n", + "\n", + "- `numpy.repeat(a, repeats, axis=None)` Repeat elements of an array.\n", + " - `axis=0`,沿着y轴复制,实际上增加了行数。\n", + " - `axis=1`,沿着x轴复制,实际上增加了列数。\n", + " - `repeats`,可以为一个数,也可以为一个矩阵。\n", + " - `axis=None`时就会flatten当前矩阵,实际上就是变成了一个行向量。\n", + "\n", + "【例】重复数组的元素。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.repeat(3, 4)\n", + "print(x) # [3 3 3 3]\n", + "\n", + "x = np.array([[1, 2], [3, 4]])\n", + "y = np.repeat(x, 2)\n", + "print(y)\n", + "# [1 1 2 2 3 3 4 4]\n", + "\n", + "y = np.repeat(x, 2, axis=0)\n", + "print(y)\n", + "# [[1 2]\n", + "# [1 2]\n", + "# [3 4]\n", + "# [3 4]]\n", + "\n", + "y = np.repeat(x, 2, axis=1)\n", + "print(y)\n", + "# [[1 1 2 2]\n", + "# [3 3 4 4]]\n", + "\n", + "y = np.repeat(x, [2, 3], axis=0)\n", + "print(y)\n", + "# [[1 2]\n", + "# [1 2]\n", + "# [3 4]\n", + "# [3 4]\n", + "# [3 4]]\n", + "\n", + "y = np.repeat(x, [2, 3], axis=1)\n", + "print(y)\n", + "# [[1 1 2 2 2]\n", + "# [3 3 4 4 4]]\n", + "```\n", + "\n", + "---\n", + "## 添加和删除元素\n", + "\n", + "- `numpy.unique(ar, return_index=False, return_inverse=False,return_counts=False, axis=None)` Find the unique elements of an array.\n", + " - return_index:the indices of the input array that give the unique values\n", + " - return_inverse:the indices of the unique array that reconstruct the input array\n", + " - return_counts:the number of times each unique value comes up in the input array\n", + "\n", + "\n", + "\n", + "\n", + "【例】查找数组的唯一元素。\n", + "```python\n", + "a=np.array([1,1,2,3,3,4,4])\n", + "b=np.unique(a,return_counts=True)\n", + "print(b[0][list(b[1]).index(1)])\n", + "#2\n", + "```\n", + "\n", + "---\n", + "**参考文献**\n", + "- https://blog.csdn.net/csdn15698845876/article/details/73380803\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "ExecuteTime": { + "end_time": "2020-08-30T13:01:49.899843Z", + "start_time": "2020-08-30T13:01:49.895853Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "a=np.array([1,1,2,3,3,4,4])\n", + "b=np.unique(a,return_counts=True)\n", + "print(b[0][list(b[1]).index(1)])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "307.193px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/.ipynb_checkpoints/练习-数组操作-变形-checkpoint.ipynb b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/.ipynb_checkpoints/练习-数组操作-变形-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/.ipynb_checkpoints/练习-数组操作-变形-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/.ipynb_checkpoints/练习-数组操作-变形-答案-checkpoint.ipynb b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/.ipynb_checkpoints/练习-数组操作-变形-答案-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/.ipynb_checkpoints/练习-数组操作-变形-答案-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/06. 数组操作.ipynb b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/06. 数组操作.ipynb new file mode 100644 index 0000000..d149a43 --- /dev/null +++ b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/06. 数组操作.ipynb @@ -0,0 +1,940 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 数组操作\n", + "\n", + "## 更改形状\n", + "\n", + "在对数组进行操作时,为了满足格式和计算的要求通常会改变其形状。\n", + "\n", + "- `numpy.ndarray.shape`表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 `ndim` 属性(秩)。\n", + "\n", + "【例】通过修改 shap 属性来改变数组的形状。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 9, 4, 5, 6, 7, 8])\n", + "print(x.shape) # (8,)\n", + "x.shape = [2, 4]\n", + "print(x)\n", + "# [[1 2 9 4]\n", + "# [5 6 7 8]]\n", + "```\n", + "\n", + "- `numpy.ndarray.flat` 将数组转换为一维的迭代器,可以用for访问数组每一个元素。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x.flat\n", + "print(y)\n", + "# \n", + "for i in y:\n", + " print(i, end=' ')\n", + "# 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35\n", + "\n", + "y[3] = 0\n", + "print(end='\\n')\n", + "print(x)\n", + "# [[11 12 13 0 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "```\n", + "\n", + "- `numpy.ndarray.flatten([order='C'])` 将数组的副本转换为一维数组,并返回。\n", + " - order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序。(简记)\n", + " - order:{'C / F,'A,K},可选使用此索引顺序读取a的元素。'C'意味着以行大的C风格顺序对元素进行索引,最后一个轴索引会更改F表示以列大的Fortran样式顺序索引元素,其中第一个索引变化最快,最后一个索引变化最快。请注意,'C'和'F'选项不考虑基础数组的内存布局,仅引用轴索引的顺序.A'表示如果a为Fortran,则以类似Fortran的索引顺序读取元素在内存中连续,否则类似C的顺序。“ K”表示按照步序在内存中的顺序读取元素,但步幅为负时反转数据除外。默认情况下,使用Cindex顺序。\n", + "\n", + "【例】`flatten()`函数返回的是拷贝。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x.flatten()\n", + "print(y)\n", + "# [11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34\n", + "# 35]\n", + "\n", + "y[3] = 0\n", + "print(x)\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = x.flatten(order='F')\n", + "print(y)\n", + "# [11 16 21 26 31 12 17 22 27 32 13 18 23 28 33 14 19 24 29 34 15 20 25 30\n", + "# 35]\n", + "\n", + "y[3] = 0\n", + "print(x)\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "```\n", + "\n", + "\n", + "\n", + "- `numpy.ravel(a, order='C')`Return a contiguous flattened array.\n", + "\n", + "【例】`ravel()`返回的是视图。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.ravel(x)\n", + "print(y)\n", + "# [11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34\n", + "# 35]\n", + "\n", + "y[3] = 0\n", + "print(x)\n", + "# [[11 12 13 0 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "\n", + "【例】order=F 就是拷贝\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = np.ravel(x, order='F')\n", + "print(y)\n", + "# [11 16 21 26 31 12 17 22 27 32 13 18 23 28 33 14 19 24 29 34 15 20 25 30\n", + "# 35]\n", + "\n", + "y[3] = 0\n", + "print(x)\n", + "# [[11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [31 32 33 34 35]]\n", + "```\n", + "\n", + "- `numpy.reshape(a, newshape[, order='C'])`在不更改数据的情况下为数组赋予新的形状。\n", + "\n", + "【例】`reshape()`函数当参数`newshape = [rows,-1]`时,将根据行数自动确定列数。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(12)\n", + "y = np.reshape(x, [3, 4])\n", + "print(y.dtype) # int32\n", + "print(y)\n", + "# [[ 0 1 2 3]\n", + "# [ 4 5 6 7]\n", + "# [ 8 9 10 11]]\n", + "\n", + "y = np.reshape(x, [3, -1])\n", + "print(y)\n", + "# [[ 0 1 2 3]\n", + "# [ 4 5 6 7]\n", + "# [ 8 9 10 11]]\n", + "\n", + "y = np.reshape(x,[-1,3])\n", + "print(y)\n", + "# [[ 0 1 2]\n", + "# [ 3 4 5]\n", + "# [ 6 7 8]\n", + "# [ 9 10 11]]\n", + "\n", + "y[0, 1] = 10\n", + "print(x)\n", + "# [ 0 10 2 3 4 5 6 7 8 9 10 11](改变x去reshape后y中的值,x对应元素也改变)\n", + "```\n", + "\n", + "【例】`reshape()`函数当参数`newshape = -1`时,表示将数组降为一维。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.random.randint(12, size=[2, 2, 3])\n", + "print(x)\n", + "# [[[11 9 1]\n", + "# [ 1 10 3]]\n", + "# \n", + "# [[ 0 6 1]\n", + "# [ 4 11 3]]]\n", + "y = np.reshape(x, -1)\n", + "print(y)\n", + "# [11 9 1 1 10 3 0 6 1 4 11 3]\n", + "```\n", + "\n", + "\n", + "\n", + "## 数组转置\n", + "\n", + "\n", + "- `numpy.transpose(a, axes=None)` Permute the dimensions of an array.\n", + "- `numpy.ndarray.T` Same as `self.transpose()`, except that self is returned if `self.ndim < 2`.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.random.rand(5, 5) * 10\n", + "x = np.around(x, 2)\n", + "print(x)\n", + "# [[6.74 8.46 6.74 5.45 1.25]\n", + "# [3.54 3.49 8.62 1.94 9.92]\n", + "# [5.03 7.22 1.6 8.7 0.43]\n", + "# [7.5 7.31 5.69 9.67 7.65]\n", + "# [1.8 9.52 2.78 5.87 4.14]]\n", + "y = x.T\n", + "print(y)\n", + "# [[6.74 3.54 5.03 7.5 1.8 ]\n", + "# [8.46 3.49 7.22 7.31 9.52]\n", + "# [6.74 8.62 1.6 5.69 2.78]\n", + "# [5.45 1.94 8.7 9.67 5.87]\n", + "# [1.25 9.92 0.43 7.65 4.14]]\n", + "y = np.transpose(x)\n", + "print(y)\n", + "# [[6.74 3.54 5.03 7.5 1.8 ]\n", + "# [8.46 3.49 7.22 7.31 9.52]\n", + "# [6.74 8.62 1.6 5.69 2.78]\n", + "# [5.45 1.94 8.7 9.67 5.87]\n", + "# [1.25 9.92 0.43 7.65 4.14]]\n", + "```\n", + "\n", + "\n", + "## 更改维度\n", + "\n", + "当创建一个数组之后,还可以给它增加一个维度,这在矩阵计算中经常会用到。\n", + "\n", + "- `numpy.newaxis = None` `None`的别名,对索引数组很有用。\n", + "\n", + "【例】很多工具包在进行计算时都会先判断输入数据的维度是否满足要求,如果输入数据达不到指定的维度时,可以使用`newaxis`参数来增加一个维度。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 9, 4, 5, 6, 7, 8])\n", + "print(x.shape) # (8,)\n", + "print(x) # [1 2 9 4 5 6 7 8]\n", + "\n", + "y = x[np.newaxis, :]\n", + "print(y.shape) # (1, 8)\n", + "print(y) # [[1 2 9 4 5 6 7 8]]\n", + "\n", + "y = x[:, np.newaxis]\n", + "print(y.shape) # (8, 1)\n", + "print(y)\n", + "# [[1]\n", + "# [2]\n", + "# [9]\n", + "# [4]\n", + "# [5]\n", + "# [6]\n", + "# [7]\n", + "# [8]]\n", + "```\n", + "\n", + "- `numpy.squeeze(a, axis=None)` 从数组的形状中删除单维度条目,即把shape中为1的维度去掉。\n", + " - `a`表示输入的数组;\n", + " - `axis`用于指定需要删除的维度,但是指定的维度必须为单维度,否则将会报错;\n", + "\n", + "在机器学习和深度学习中,通常算法的结果是可以表示向量的数组(即包含两对或以上的方括号形式[[]]),如果直接利用这个数组进行画图可能显示界面为空(见后面的示例)。我们可以利用`squeeze()`函数将表示向量的数组转换为秩为1的数组,这样利用 matplotlib 库函数画图时,就可以正常的显示结果了。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(10)\n", + "print(x.shape) # (10,)\n", + "x = x[np.newaxis, :]\n", + "print(x.shape) # (1, 10)\n", + "y = np.squeeze(x)\n", + "print(y.shape) # (10,)\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[[0], [1], [2]]])\n", + "print(x.shape) # (1, 3, 1)\n", + "print(x)\n", + "# [[[0]\n", + "# [1]\n", + "# [2]]]\n", + "\n", + "y = np.squeeze(x)\n", + "print(y.shape) # (3,)\n", + "print(y) # [0 1 2]\n", + "\n", + "y = np.squeeze(x, axis=0)\n", + "print(y.shape) # (3, 1)\n", + "print(y)\n", + "# [[0]\n", + "# [1]\n", + "# [2]]\n", + "\n", + "y = np.squeeze(x, axis=2)\n", + "print(y.shape) # (1, 3)\n", + "print(y) # [[0 1 2]]\n", + "\n", + "y = np.squeeze(x, axis=1)\n", + "# ValueError: cannot select an axis to squeeze out which has size not equal to one\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "x = np.array([[1, 4, 9, 16, 25]])\n", + "print(x.shape) # (1, 5)\n", + "plt.plot(x)\n", + "plt.show()\n", + "```\n", + "![](https://img-blog.csdnimg.cn/20200528095957317.png)\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "x = np.array([[1, 4, 9, 16, 25]])\n", + "x = np.squeeze(x)\n", + "print(x.shape) # (5, )\n", + "plt.plot(x)\n", + "plt.show()\n", + "```\n", + "\n", + "![](https://img-blog.csdnimg.cn/20200528100221464.png)\n", + "\n", + "## 数组组合\n", + "\n", + "如果要将两份数据组合到一起,就需要拼接操作。\n", + "\n", + "- `numpy.concatenate((a1, a2, ...), axis=0, out=None)` Join a sequence of arrays along an existing axis.\n", + "\n", + "【例】连接沿现有轴的数组序列(原来x,y都是一维的,拼接后的结果也是一维的)。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3])\n", + "y = np.array([7, 8, 9])\n", + "z = np.concatenate([x, y])\n", + "print(z)\n", + "# [1 2 3 7 8 9]\n", + "\n", + "z = np.concatenate([x, y], axis=0)\n", + "print(z)\n", + "# [1 2 3 7 8 9]\n", + "```\n", + "\n", + "【例】原来x,y都是二维的,拼接后的结果也是二维的。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3]).reshape(1, 3)\n", + "y = np.array([7, 8, 9]).reshape(1, 3)\n", + "z = np.concatenate([x, y])\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 7 8 9]]\n", + "z = np.concatenate([x, y], axis=0)\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 7 8 9]]\n", + "z = np.concatenate([x, y], axis=1)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]]\n", + "```\n", + "\n", + "【例】x,y在原来的维度上进行拼接。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.array([[7, 8, 9], [10, 11, 12]])\n", + "z = np.concatenate([x, y])\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 4 5 6]\n", + "# [ 7 8 9]\n", + "# [10 11 12]]\n", + "z = np.concatenate([x, y], axis=0)\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 4 5 6]\n", + "# [ 7 8 9]\n", + "# [10 11 12]]\n", + "z = np.concatenate([x, y], axis=1)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]\n", + "# [ 4 5 6 10 11 12]]\n", + "```\n", + "\n", + "- `numpy.stack(arrays, axis=0, out=None)`Join a sequence of arrays along a new axis.\n", + "\n", + "\n", + "【例】沿着新的轴加入一系列数组(stack为增加维度的拼接)。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3])\n", + "y = np.array([7, 8, 9])\n", + "z = np.stack([x, y])\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.stack([x, y], axis=1)\n", + "print(z.shape) # (3, 2)\n", + "print(z)\n", + "# [[1 7]\n", + "# [2 8]\n", + "# [3 9]]\n", + "```\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3]).reshape(1, 3)\n", + "y = np.array([7, 8, 9]).reshape(1, 3)\n", + "z = np.stack([x, y])\n", + "print(z.shape) # (2, 1, 3)\n", + "print(z)\n", + "# [[[1 2 3]]\n", + "#\n", + "# [[7 8 9]]]\n", + "\n", + "z = np.stack([x, y], axis=1)\n", + "print(z.shape) # (1, 2, 3)\n", + "print(z)\n", + "# [[[1 2 3]\n", + "# [7 8 9]]]\n", + "\n", + "z = np.stack([x, y], axis=2)\n", + "print(z.shape) # (1, 3, 2)\n", + "print(z)\n", + "# [[[1 7]\n", + "# [2 8]\n", + "# [3 9]]]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.array([[7, 8, 9], [10, 11, 12]])\n", + "z = np.stack([x, y])\n", + "print(z.shape) # (2, 2, 3)\n", + "print(z)\n", + "# [[[ 1 2 3]\n", + "# [ 4 5 6]]\n", + "# \n", + "# [[ 7 8 9]\n", + "# [10 11 12]]]\n", + "\n", + "z = np.stack([x, y], axis=1)\n", + "print(z.shape) # (2, 2, 3)\n", + "print(z)\n", + "# [[[ 1 2 3]\n", + "# [ 7 8 9]]\n", + "# \n", + "# [[ 4 5 6]\n", + "# [10 11 12]]]\n", + "\n", + "z = np.stack([x, y], axis=2)\n", + "print(z.shape) # (2, 3, 2)\n", + "print(z)\n", + "# [[[ 1 7]\n", + "# [ 2 8]\n", + "# [ 3 9]]\n", + "# \n", + "# [[ 4 10]\n", + "# [ 5 11]\n", + "# [ 6 12]]]\n", + "```\n", + "\n", + "\n", + "- `numpy.vstack(tup)`Stack arrays in sequence vertically (row wise).\n", + "- `numpy.hstack(tup)`Stack arrays in sequence horizontally (column wise). \n", + "\n", + "\n", + "【例】一维的情况。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3])\n", + "y = np.array([7, 8, 9])\n", + "z = np.vstack((x, y))\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.stack([x, y])\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.hstack((x, y))\n", + "print(z.shape) # (6,)\n", + "print(z)\n", + "# [1 2 3 7 8 9]\n", + "\n", + "z = np.concatenate((x, y))\n", + "print(z.shape) # (6,)\n", + "print(z) # [1 2 3 7 8 9]\n", + "```\n", + "\n", + "\n", + "\n", + "【例】二维的情况。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3]).reshape(1, 3)\n", + "y = np.array([7, 8, 9]).reshape(1, 3)\n", + "z = np.vstack((x, y))\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.concatenate((x, y), axis=0)\n", + "print(z.shape) # (2, 3)\n", + "print(z)\n", + "# [[1 2 3]\n", + "# [7 8 9]]\n", + "\n", + "z = np.hstack((x, y))\n", + "print(z.shape) # (1, 6)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]]\n", + "\n", + "z = np.concatenate((x, y), axis=1)\n", + "print(z.shape) # (1, 6)\n", + "print(z)\n", + "# [[1 2 3 7 8 9]]\n", + "```\n", + "\n", + "【例】二维的情况。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6]])\n", + "y = np.array([[7, 8, 9], [10, 11, 12]])\n", + "z = np.vstack((x, y))\n", + "print(z.shape) # (4, 3)\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 4 5 6]\n", + "# [ 7 8 9]\n", + "# [10 11 12]]\n", + "\n", + "z = np.concatenate((x, y), axis=0)\n", + "print(z.shape) # (4, 3)\n", + "print(z)\n", + "# [[ 1 2 3]\n", + "# [ 4 5 6]\n", + "# [ 7 8 9]\n", + "# [10 11 12]]\n", + "\n", + "z = np.hstack((x, y))\n", + "print(z.shape) # (2, 6)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]\n", + "# [ 4 5 6 10 11 12]]\n", + "\n", + "z = np.concatenate((x, y), axis=1)\n", + "print(z.shape) # (2, 6)\n", + "print(z)\n", + "# [[ 1 2 3 7 8 9]\n", + "# [ 4 5 6 10 11 12]]\n", + "```\n", + "\n", + "`hstack(),vstack()`分别表示水平和竖直的拼接方式。在数据维度等于1时,比较特殊。而当维度大于或等于2时,它们的作用相当于`concatenate`,用于在已有轴上进行操作。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.hstack([np.array([1, 2, 3, 4]), 5])\n", + "print(a) # [1 2 3 4 5]\n", + "\n", + "a = np.concatenate([np.array([1, 2, 3, 4]), 5])\n", + "print(a)\n", + "# all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 0 dimension(s)\n", + "```\n", + "\n", + "\n", + "## 数组拆分\n", + "\n", + "- `numpy.split(ary, indices_or_sections, axis=0)` Split an array into multiple sub-arrays as views into ary.\n", + "\n", + "【例】拆分数组。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14],\n", + " [16, 17, 18, 19],\n", + " [21, 22, 23, 24]])\n", + "y = np.split(x, [1, 3])\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]]), array([], shape=(0, 4), dtype=int32)]\n", + "\n", + "y = np.split(x, [1, 3], axis=1)\n", + "print(y)\n", + "# [array([[11],\n", + "# [16],\n", + "# [21]]), array([[12, 13],\n", + "# [17, 18],\n", + "# [22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "```\n", + "\n", + "\n", + "\n", + "- `numpy.vsplit(ary, indices_or_sections)` Split an array into multiple sub-arrays vertically (row-wise).\n", + "\n", + "【例】垂直切分是把数组按照高度切分\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14],\n", + " [16, 17, 18, 19],\n", + " [21, 22, 23, 24]])\n", + "y = np.vsplit(x, 3)\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19]]), array([[21, 22, 23, 24]])]\n", + "\n", + "y = np.split(x, 3)\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19]]), array([[21, 22, 23, 24]])]\n", + "\n", + "\n", + "y = np.vsplit(x, [1])\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]])]\n", + "\n", + "y = np.split(x, [1])\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]])]\n", + "\n", + "\n", + "y = np.vsplit(x, [1, 3])\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]]), array([], shape=(0, 4), dtype=int32)]\n", + "y = np.split(x, [1, 3], axis=0)\n", + "print(y)\n", + "# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],\n", + "# [21, 22, 23, 24]]), array([], shape=(0, 4), dtype=int32)]\n", + "```\n", + "\n", + "- `numpy.hsplit(ary, indices_or_sections)` Split an array into multiple sub-arrays horizontally (column-wise).\n", + "\n", + "\n", + "【例】水平切分是把数组按照宽度切分。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14],\n", + " [16, 17, 18, 19],\n", + " [21, 22, 23, 24]])\n", + "y = np.hsplit(x, 2)\n", + "print(y)\n", + "# [array([[11, 12],\n", + "# [16, 17],\n", + "# [21, 22]]), array([[13, 14],\n", + "# [18, 19],\n", + "# [23, 24]])]\n", + "\n", + "y = np.split(x, 2, axis=1)\n", + "print(y)\n", + "# [array([[11, 12],\n", + "# [16, 17],\n", + "# [21, 22]]), array([[13, 14],\n", + "# [18, 19],\n", + "# [23, 24]])]\n", + "\n", + "y = np.hsplit(x, [3])\n", + "print(y)\n", + "# [array([[11, 12, 13],\n", + "# [16, 17, 18],\n", + "# [21, 22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "\n", + "y = np.split(x, [3], axis=1)\n", + "print(y)\n", + "# [array([[11, 12, 13],\n", + "# [16, 17, 18],\n", + "# [21, 22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "\n", + "y = np.hsplit(x, [1, 3])\n", + "print(y)\n", + "# [array([[11],\n", + "# [16],\n", + "# [21]]), array([[12, 13],\n", + "# [17, 18],\n", + "# [22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "\n", + "y = np.split(x, [1, 3], axis=1)\n", + "print(y)\n", + "# [array([[11],\n", + "# [16],\n", + "# [21]]), array([[12, 13],\n", + "# [17, 18],\n", + "# [22, 23]]), array([[14],\n", + "# [19],\n", + "# [24]])]\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "## 数组平铺\n", + "\n", + "- `numpy.tile(A, reps)` Construct an array by repeating A the number of times given by reps.\n", + "\n", + "`tile`是瓷砖的意思,顾名思义,这个函数就是把数组像瓷砖一样铺展开来。\n", + "\n", + "【例】将原矩阵横向、纵向地复制。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2], [3, 4]])\n", + "print(x)\n", + "# [[1 2]\n", + "# [3 4]]\n", + "\n", + "y = np.tile(x, (1, 3))\n", + "print(y)\n", + "# [[1 2 1 2 1 2]\n", + "# [3 4 3 4 3 4]]\n", + "\n", + "y = np.tile(x, (3, 1))\n", + "print(y)\n", + "# [[1 2]\n", + "# [3 4]\n", + "# [1 2]\n", + "# [3 4]\n", + "# [1 2]\n", + "# [3 4]]\n", + "\n", + "y = np.tile(x, (3, 3))\n", + "print(y)\n", + "# [[1 2 1 2 1 2]\n", + "# [3 4 3 4 3 4]\n", + "# [1 2 1 2 1 2]\n", + "# [3 4 3 4 3 4]\n", + "# [1 2 1 2 1 2]\n", + "# [3 4 3 4 3 4]]\n", + "```\n", + "\n", + "- `numpy.repeat(a, repeats, axis=None)` Repeat elements of an array.\n", + " - `axis=0`,沿着y轴复制,实际上增加了行数。\n", + " - `axis=1`,沿着x轴复制,实际上增加了列数。\n", + " - `repeats`,可以为一个数,也可以为一个矩阵。\n", + " - `axis=None`时就会flatten当前矩阵,实际上就是变成了一个行向量。\n", + "\n", + "【例】重复数组的元素。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.repeat(3, 4)\n", + "print(x) # [3 3 3 3]\n", + "\n", + "x = np.array([[1, 2], [3, 4]])\n", + "y = np.repeat(x, 2)\n", + "print(y)\n", + "# [1 1 2 2 3 3 4 4]\n", + "\n", + "y = np.repeat(x, 2, axis=0)\n", + "print(y)\n", + "# [[1 2]\n", + "# [1 2]\n", + "# [3 4]\n", + "# [3 4]]\n", + "\n", + "y = np.repeat(x, 2, axis=1)\n", + "print(y)\n", + "# [[1 1 2 2]\n", + "# [3 3 4 4]]\n", + "\n", + "y = np.repeat(x, [2, 3], axis=0)\n", + "print(y)\n", + "# [[1 2]\n", + "# [1 2]\n", + "# [3 4]\n", + "# [3 4]\n", + "# [3 4]]\n", + "\n", + "y = np.repeat(x, [2, 3], axis=1)\n", + "print(y)\n", + "# [[1 1 2 2 2]\n", + "# [3 3 4 4 4]]\n", + "```\n", + "\n", + "---\n", + "## 添加和删除元素\n", + "\n", + "- `numpy.unique(ar, return_index=False, return_inverse=False,return_counts=False, axis=None)` Find the unique elements of an array.\n", + " - return_index:the indices of the input array that give the unique values\n", + " - return_inverse:the indices of the unique array that reconstruct the input array\n", + " - return_counts:the number of times each unique value comes up in the input array\n", + "\n", + "\n", + "\n", + "\n", + "【例】查找数组的唯一元素。\n", + "```python\n", + "a=np.array([1,1,2,3,3,4,4])\n", + "b=np.unique(a,return_counts=True)\n", + "print(b[0][list(b[1]).index(1)])\n", + "#2\n", + "```\n", + "\n", + "---\n", + "**参考文献**\n", + "- https://blog.csdn.net/csdn15698845876/article/details/73380803\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "ExecuteTime": { + "end_time": "2020-08-30T13:01:49.899843Z", + "start_time": "2020-08-30T13:01:49.895853Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "a=np.array([1,1,2,3,3,4,4])\n", + "b=np.unique(a,return_counts=True)\n", + "print(b[0][list(b[1]).index(1)])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "307.193px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/练习-数组操作-变形-答案.ipynb b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/练习-数组操作-变形-答案.ipynb new file mode 100644 index 0000000..e5c2177 --- /dev/null +++ b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/练习-数组操作-变形-答案.ipynb @@ -0,0 +1,309 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**将 `arr`转换为2行的2维数组。**\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:数组的操作】\n", + "- 如何改变数组的形状?" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:47:23.972422Z", + "start_time": "2020-09-06T02:47:23.965489Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2 3 4]\n", + " [5 6 7 8 9]]\n", + "[[0 1 2 3 4]\n", + " [5 6 7 8 9]]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "arr = np.arange(10)\n", + "\n", + "# 方法1\n", + "x = np.reshape(arr, newshape=[2, 5])\n", + "print(x)\n", + "# [[0 1 2 3 4]\n", + "# [5 6 7 8 9]]\n", + "\n", + "# 方法2\n", + "x = np.reshape(arr, newshape=[2, -1])\n", + "print(x)\n", + "# [[0 1 2 3 4]\n", + "# [5 6 7 8 9]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**垂直堆叠数组a和数组b。**\n", + "- `a = np.arange(10).reshape([2, -1])`\n", + "- `b = np.repeat(1, 10).reshape([2, -1])`\n", + "\n", + "【知识点:数组操作】\n", + "- 如何垂直叠加两个数组?" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:48:08.620475Z", + "start_time": "2020-09-06T02:48:08.614519Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2 3 4]\n", + " [5 6 7 8 9]]\n", + "[[1 1 1 1 1]\n", + " [1 1 1 1 1]]\n", + "[[0 1 2 3 4]\n", + " [5 6 7 8 9]\n", + " [1 1 1 1 1]\n", + " [1 1 1 1 1]]\n", + "[[0 1 2 3 4]\n", + " [5 6 7 8 9]\n", + " [1 1 1 1 1]\n", + " [1 1 1 1 1]]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.arange(10).reshape([2, -1])\n", + "b = np.repeat(1, 10).reshape([2, -1])\n", + "\n", + "print(a)\n", + "# [[0 1 2 3 4]\n", + "# [5 6 7 8 9]]\n", + "print(b)\n", + "# [[1 1 1 1 1]\n", + "# [1 1 1 1 1]]\n", + "\n", + "# 方法1\n", + "print(np.concatenate([a, b], axis=0))\n", + "# [[0 1 2 3 4]\n", + "# [5 6 7 8 9]\n", + "# [1 1 1 1 1]\n", + "# [1 1 1 1 1]]\n", + "\n", + "# 方法2\n", + "print(np.vstack([a, b]))\n", + "# [[0 1 2 3 4]\n", + "# [5 6 7 8 9]\n", + "# [1 1 1 1 1]\n", + "# [1 1 1 1 1]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**8. 将数组a与数组b水平堆叠。**\n", + "- `a = np.arange(10).reshape([2, -1])`\n", + "- `b = np.repeat(1, 10).reshape([2, -1])`\n", + "\n", + "【知识点:数组的操作】\n", + "- 如何水平叠加两个数组?" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:48:41.235432Z", + "start_time": "2020-09-06T02:48:41.229447Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2 3 4]\n", + " [5 6 7 8 9]]\n", + "[[1 1 1 1 1]\n", + " [1 1 1 1 1]]\n", + "[[0 1 2 3 4 1 1 1 1 1]\n", + " [5 6 7 8 9 1 1 1 1 1]]\n", + "[[0 1 2 3 4 1 1 1 1 1]\n", + " [5 6 7 8 9 1 1 1 1 1]]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.arange(10).reshape([2, -1])\n", + "b = np.repeat(1, 10).reshape([2, -1])\n", + "\n", + "print(a)\n", + "# [[0 1 2 3 4]\n", + "# [5 6 7 8 9]]\n", + "print(b)\n", + "# [[1 1 1 1 1]\n", + "# [1 1 1 1 1]]\n", + "\n", + "# 方法1\n", + "print(np.concatenate([a, b], axis=1))\n", + "# [[0 1 2 3 4 1 1 1 1 1]\n", + "# [5 6 7 8 9 1 1 1 1 1]]\n", + "\n", + "# 方法2\n", + "print(np.hstack([a, b]))\n", + "# [[0 1 2 3 4 1 1 1 1 1]\n", + "# [5 6 7 8 9 1 1 1 1 1]]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:15:03.024776Z", + "start_time": "2020-09-06T03:15:03.019739Z" + } + }, + "source": [ + "**在给定的numpy数组中找到重复的条目(第二次出现以后),并将它们标记为True。第一次出现应为False。**\n", + "\n", + "- `a = np.random.randint(0, 5, 10)`\n", + "\n", + "【知识点:数组操作】\n", + "- 如何在numpy数组中找到重复值?" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:15:33.059248Z", + "start_time": "2020-09-06T03:15:33.054241Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 0 3 0 2 4 2 2 2 2]\n", + "[False True False True False False True True True True]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "a = np.random.randint(0, 5, 10)\n", + "print(a)\n", + "# [0 0 3 0 2 4 2 2 2 2]\n", + "b = np.full(10, True)\n", + "vals, counts = np.unique(a, return_index=True)\n", + "b[counts] = False\n", + "print(b)\n", + "# [False True False True False False True True True True]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/练习-数组操作-变形.ipynb b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/练习-数组操作-变形.ipynb new file mode 100644 index 0000000..cdcf890 --- /dev/null +++ b/IntroductionToNumpy/numpy/task03-2天-数组的操作-变形/练习-数组操作-变形.ipynb @@ -0,0 +1,121 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **将 `arr`转换为2行的2维数组。**\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:数组的操作】\n", + "- 如何改变数组的形状?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **垂直堆叠数组a和数组b。**\n", + "- `a = np.arange(10).reshape([2, -1])`\n", + "- `b = np.repeat(1, 10).reshape([2, -1])`\n", + "\n", + "【知识点:数组操作】\n", + "- 如何垂直叠加两个数组?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **8. 将数组a与数组b水平堆叠。**\n", + "- `a = np.arange(10).reshape([2, -1])`\n", + "- `b = np.repeat(1, 10).reshape([2, -1])`\n", + "\n", + "【知识点:数组的操作】\n", + "- 如何水平叠加两个数组?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **在给定的numpy数组中找到重复的条目(第二次出现以后),并将它们标记为True。第一次出现应为False。**\n", + "\n", + "- `a = np.random.randint(0, 5, 10)`\n", + "\n", + "【知识点:数组操作】\n", + "- 如何在numpy数组中找到重复值?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/07. 数学函数-checkpoint.ipynb b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/07. 数学函数-checkpoint.ipynb new file mode 100644 index 0000000..3d68b89 --- /dev/null +++ b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/07. 数学函数-checkpoint.ipynb @@ -0,0 +1,828 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 向量化和广播\n", + "\n", + "向量化和广播这两个概念是 numpy 内部实现的基础。有了向量化,编写代码时无需使用显式循环。这些循环实际上不能省略,只不过是在内部实现,被代码中的其他结构代替。向量化的应用使得代码更简洁,可读性更强,也可以说使用了向量化方法的代码看上去更“Pythonic”。\n", + "\n", + "广播(Broadcasting)机制描述了 numpy 如何在算术运算期间处理具有不同形状的数组,让较小的数组在较大的数组上“广播”,以便它们具有兼容的形状。并不是所有的维度都要彼此兼容才符合广播机制的要求,但它们必须满足一定的条件。\n", + "\n", + "若两个数组的各维度兼容,也就是两个数组的每一维等长,或其中一个数组为 一维,那么广播机制就适用。如果这两个条件不满足,numpy就会抛出异常,说两个数组不兼容。\n", + "\n", + "总结来说,广播的规则有三个:\n", + "- 如果两个数组的维度数dim不相同,那么小维度数组的形状将会在左边补1。\n", + "- 如果shape维度不匹配,但是有维度是1,那么可以扩展维度是1的维度匹配另一个数组;\n", + "- 如果shape维度不匹配,但是没有任何一个维度是1,则匹配引发错误;\n", + "\n", + "【例】二维数组加一维数组\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(4)\n", + "y = np.ones((3, 4))\n", + "print(x.shape) # (4,)\n", + "print(y.shape) # (3, 4)\n", + "\n", + "print((x + y).shape) # (3, 4)\n", + "print(x + y)\n", + "# [[1. 2. 3. 4.]\n", + "# [1. 2. 3. 4.]\n", + "# [1. 2. 3. 4.]]\n", + "```\n", + "\n", + "\n", + "【例】两个数组均需要广播\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(4).reshape(4, 1)\n", + "y = np.ones(5)\n", + "\n", + "print(x.shape) # (4, 1)\n", + "print(y.shape) # (5,)\n", + "\n", + "print((x + y).shape) # (4, 5)\n", + "print(x + y)\n", + "# [[1. 1. 1. 1. 1.]\n", + "# [2. 2. 2. 2. 2.]\n", + "# [3. 3. 3. 3. 3.]\n", + "# [4. 4. 4. 4. 4.]]\n", + "\n", + "x = np.array([0.0, 10.0, 20.0, 30.0])\n", + "y = np.array([1.0, 2.0, 3.0])\n", + "z = x[:, np.newaxis] + y\n", + "print(z)\n", + "# [[ 1. 2. 3.]\n", + "# [11. 12. 13.]\n", + "# [21. 22. 23.]\n", + "# [31. 32. 33.]]\n", + "```\n", + "\n", + "【例】不匹配报错的例子\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(4)\n", + "y = np.ones(5)\n", + "\n", + "print(x.shape) # (4,)\n", + "print(y.shape) # (5,)\n", + "\n", + "print(x + y)\n", + "# ValueError: operands could not be broadcast together with shapes (4,) (5,) \n", + "```\n", + "\n", + "\n", + "---\n", + "# 数学函数\n", + "\n", + "\n", + "## 算数运算\n", + "### numpy.add\n", + "### numpy.subtract\n", + "### numpy.multiply\n", + "\n", + "- `numpy.add(x1, x2, *args, **kwargs)` Add arguments element-wise.\n", + "- `numpy.subtract(x1, x2, *args, **kwargs)` Subtract arguments element-wise.\n", + "- `numpy.multiply(x1, x2, *args, **kwargs)` Multiply arguments element-wise.\n", + "- `numpy.divide(x1, x2, *args, **kwargs)` Returns a true division of the inputs, element-wise.\n", + "- `numpy.floor_divide(x1, x2, *args, **kwargs)` Return the largest integer smaller or equal to the division of the inputs.\n", + "- `numpy.power(x1, x2, *args, **kwargs)` First array elements raised to powers from second array, element-wise.\n", + "\n", + "在 numpy 中对以上函数进行了运算符的重载,且运算符为 **元素级**。也就是说,它们只用于位置相同的元素之间,所得到的运算结果组成一个新的数组。\n", + "\n", + "【例】注意 numpy 的广播规则。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "y = x + 1\n", + "print(y)\n", + "print(np.add(x, 1))\n", + "# [2 3 4 5 6 7 8 9]\n", + "\n", + "y = x - 1\n", + "print(y)\n", + "print(np.subtract(x, 1))\n", + "# [0 1 2 3 4 5 6 7]\n", + "\n", + "y = x * 2\n", + "print(y)\n", + "print(np.multiply(x, 2))\n", + "# [ 2 4 6 8 10 12 14 16]\n", + "\n", + "y = x / 2\n", + "print(y)\n", + "print(np.divide(x, 2))\n", + "# [0.5 1. 1.5 2. 2.5 3. 3.5 4. ]\n", + "\n", + "y = x // 2\n", + "print(y)\n", + "print(np.floor_divide(x, 2))\n", + "# [0 1 1 2 2 3 3 4]\n", + "\n", + "y = x ** 2\n", + "print(y)\n", + "print(np.power(x, 2))\n", + "# [ 1 4 9 16 25 36 49 64]\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "【例】注意 numpy 的广播规则。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x + 1\n", + "print(y)\n", + "print(np.add(x, 1))\n", + "# [[12 13 14 15 16]\n", + "# [17 18 19 20 21]\n", + "# [22 23 24 25 26]\n", + "# [27 28 29 30 31]\n", + "# [32 33 34 35 36]]\n", + "\n", + "y = x - 1\n", + "print(y)\n", + "print(np.subtract(x, 1))\n", + "# [[10 11 12 13 14]\n", + "# [15 16 17 18 19]\n", + "# [20 21 22 23 24]\n", + "# [25 26 27 28 29]\n", + "# [30 31 32 33 34]]\n", + "\n", + "y = x * 2\n", + "print(y)\n", + "print(np.multiply(x, 2))\n", + "# [[22 24 26 28 30]\n", + "# [32 34 36 38 40]\n", + "# [42 44 46 48 50]\n", + "# [52 54 56 58 60]\n", + "# [62 64 66 68 70]]\n", + "\n", + "y = x / 2\n", + "print(y)\n", + "print(np.divide(x, 2))\n", + "# [[ 5.5 6. 6.5 7. 7.5]\n", + "# [ 8. 8.5 9. 9.5 10. ]\n", + "# [10.5 11. 11.5 12. 12.5]\n", + "# [13. 13.5 14. 14.5 15. ]\n", + "# [15.5 16. 16.5 17. 17.5]]\n", + "\n", + "y = x // 2\n", + "print(y)\n", + "print(np.floor_divide(x, 2))\n", + "# [[ 5 6 6 7 7]\n", + "# [ 8 8 9 9 10]\n", + "# [10 11 11 12 12]\n", + "# [13 13 14 14 15]\n", + "# [15 16 16 17 17]]\n", + "\n", + "y = x ** 2\n", + "print(y)\n", + "print(np.power(x, 2))\n", + "# [[ 121 144 169 196 225]\n", + "# [ 256 289 324 361 400]\n", + "# [ 441 484 529 576 625]\n", + "# [ 676 729 784 841 900]\n", + "# [ 961 1024 1089 1156 1225]]\n", + "```\n", + "\n", + "【例】注意 numpy 的广播规则。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = np.arange(1, 6)\n", + "print(y)\n", + "# [1 2 3 4 5]\n", + "\n", + "z = x + y\n", + "print(z)\n", + "print(np.add(x, y))\n", + "# [[12 14 16 18 20]\n", + "# [17 19 21 23 25]\n", + "# [22 24 26 28 30]\n", + "# [27 29 31 33 35]\n", + "# [32 34 36 38 40]]\n", + "\n", + "z = x - y\n", + "print(z)\n", + "print(np.subtract(x, y))\n", + "# [[10 10 10 10 10]\n", + "# [15 15 15 15 15]\n", + "# [20 20 20 20 20]\n", + "# [25 25 25 25 25]\n", + "# [30 30 30 30 30]]\n", + "\n", + "z = x * y\n", + "print(z)\n", + "print(np.multiply(x, y))\n", + "# [[ 11 24 39 56 75]\n", + "# [ 16 34 54 76 100]\n", + "# [ 21 44 69 96 125]\n", + "# [ 26 54 84 116 150]\n", + "# [ 31 64 99 136 175]]\n", + "\n", + "z = x / y\n", + "print(z)\n", + "print(np.divide(x, y))\n", + "# [[11. 6. 4.33333333 3.5 3. ]\n", + "# [16. 8.5 6. 4.75 4. ]\n", + "# [21. 11. 7.66666667 6. 5. ]\n", + "# [26. 13.5 9.33333333 7.25 6. ]\n", + "# [31. 16. 11. 8.5 7. ]]\n", + "\n", + "z = x // y\n", + "print(z)\n", + "print(np.floor_divide(x, y))\n", + "# [[11 6 4 3 3]\n", + "# [16 8 6 4 4]\n", + "# [21 11 7 6 5]\n", + "# [26 13 9 7 6]\n", + "# [31 16 11 8 7]]\n", + "\n", + "z = x ** np.full([1, 5], 2)\n", + "print(z)\n", + "print(np.power(x, np.full([5, 5], 2)))\n", + "# [[ 121 144 169 196 225]\n", + "# [ 256 289 324 361 400]\n", + "# [ 441 484 529 576 625]\n", + "# [ 676 729 784 841 900]\n", + "# [ 961 1024 1089 1156 1225]]\n", + "```\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = np.arange(1, 26).reshape([5, 5])\n", + "print(y)\n", + "# [[ 1 2 3 4 5]\n", + "# [ 6 7 8 9 10]\n", + "# [11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]]\n", + "\n", + "z = x + y\n", + "print(z)\n", + "print(np.add(x, y))\n", + "# [[12 14 16 18 20]\n", + "# [22 24 26 28 30]\n", + "# [32 34 36 38 40]\n", + "# [42 44 46 48 50]\n", + "# [52 54 56 58 60]]\n", + "\n", + "z = x - y\n", + "print(z)\n", + "print(np.subtract(x, y))\n", + "# [[10 10 10 10 10]\n", + "# [10 10 10 10 10]\n", + "# [10 10 10 10 10]\n", + "# [10 10 10 10 10]\n", + "# [10 10 10 10 10]]\n", + "\n", + "z = x * y\n", + "print(z)\n", + "print(np.multiply(x, y))\n", + "# [[ 11 24 39 56 75]\n", + "# [ 96 119 144 171 200]\n", + "# [231 264 299 336 375]\n", + "# [416 459 504 551 600]\n", + "# [651 704 759 816 875]]\n", + "\n", + "z = x / y\n", + "print(z)\n", + "print(np.divide(x, y))\n", + "# [[11. 6. 4.33333333 3.5 3. ]\n", + "# [ 2.66666667 2.42857143 2.25 2.11111111 2. ]\n", + "# [ 1.90909091 1.83333333 1.76923077 1.71428571 1.66666667]\n", + "# [ 1.625 1.58823529 1.55555556 1.52631579 1.5 ]\n", + "# [ 1.47619048 1.45454545 1.43478261 1.41666667 1.4 ]]\n", + "\n", + "z = x // y\n", + "print(z)\n", + "print(np.floor_divide(x, y))\n", + "# [[11 6 4 3 3]\n", + "# [ 2 2 2 2 2]\n", + "# [ 1 1 1 1 1]\n", + "# [ 1 1 1 1 1]\n", + "# [ 1 1 1 1 1]]\n", + "\n", + "z = x ** np.full([5, 5], 2)\n", + "print(z)\n", + "print(np.power(x, np.full([5, 5], 2)))\n", + "# [[ 121 144 169 196 225]\n", + "# [ 256 289 324 361 400]\n", + "# [ 441 484 529 576 625]\n", + "# [ 676 729 784 841 900]\n", + "# [ 961 1024 1089 1156 1225]]\n", + "```\n", + "\n", + "\n", + "\n", + "- `numpy.sqrt(x, *args, **kwargs)` Return the non-negative square-root of an array, element-wise.\n", + "- `numpy.square(x, *args, **kwargs)` Return the element-wise square of the input.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(1, 5)\n", + "print(x) # [1 2 3 4]\n", + "\n", + "y = np.sqrt(x)\n", + "print(y)\n", + "# [1. 1.41421356 1.73205081 2. ]\n", + "print(np.power(x, 0.5))\n", + "# [1. 1.41421356 1.73205081 2. ]\n", + "\n", + "y = np.square(x)\n", + "print(y)\n", + "# [ 1 4 9 16]\n", + "print(np.power(x, 2))\n", + "# [ 1 4 9 16]\n", + "```\n", + "\n", + "\n", + "---\n", + "## 三角函数\n", + "\n", + "- `numpy.sin(x, *args, **kwargs)` Trigonometric sine, element-wise.\n", + "- `numpy.cos(x, *args, **kwargs)` Cosine element-wise.\n", + "- `numpy.tan(x, *args, **kwargs)` Compute tangent element-wise.\n", + "- `numpy.arcsin(x, *args, **kwargs)` Inverse sine, element-wise.\n", + "- `numpy.arccos(x, *args, **kwargs)` Trigonometric inverse cosine, element-wise.\n", + "- `numpy.arctan(x, *args, **kwargs)` Trigonometric inverse tangent, element-wise.\n", + "\n", + "\n", + "**通用函数**(universal function)通常叫作ufunc,它对数组中的各个元素逐一进行操作。这表明,通用函数分别处理输入数组的每个元素,生成的结果组成一个新的输出数组。输出数组的大小跟输入数组相同。\n", + "\n", + "三角函数等很多数学运算符合通用函数的定义,例如,计算平方根的`sqrt()`函数、用来取对数的`log()`函数和求正弦值的`sin()`函数。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.linspace(start=0, stop=np.pi / 2, num=10)\n", + "print(x)\n", + "# [0. 0.17453293 0.34906585 0.52359878 0.6981317 0.87266463\n", + "# 1.04719755 1.22173048 1.3962634 1.57079633]\n", + "\n", + "y = np.sin(x)\n", + "print(y)\n", + "# [0. 0.17364818 0.34202014 0.5 0.64278761 0.76604444\n", + "# 0.8660254 0.93969262 0.98480775 1. ]\n", + "\n", + "z = np.arcsin(y)\n", + "print(z)\n", + "# [0. 0.17453293 0.34906585 0.52359878 0.6981317 0.87266463\n", + "# 1.04719755 1.22173048 1.3962634 1.57079633]\n", + "\n", + "y = np.cos(x)\n", + "print(y)\n", + "# [1.00000000e+00 9.84807753e-01 9.39692621e-01 8.66025404e-01\n", + "# 7.66044443e-01 6.42787610e-01 5.00000000e-01 3.42020143e-01\n", + "# 1.73648178e-01 6.12323400e-17]\n", + "\n", + "z = np.arccos(y)\n", + "print(z)\n", + "# [0. 0.17453293 0.34906585 0.52359878 0.6981317 0.87266463\n", + "# 1.04719755 1.22173048 1.3962634 1.57079633]\n", + "\n", + "y = np.tan(x)\n", + "print(y)\n", + "# [0.00000000e+00 1.76326981e-01 3.63970234e-01 5.77350269e-01\n", + "# 8.39099631e-01 1.19175359e+00 1.73205081e+00 2.74747742e+00\n", + "# 5.67128182e+00 1.63312394e+16]\n", + "\n", + "z = np.arctan(y)\n", + "print(z)\n", + "# [0. 0.17453293 0.34906585 0.52359878 0.6981317 0.87266463\n", + "# 1.04719755 1.22173048 1.3962634 1.57079633]\n", + "```\n", + "\n", + "---\n", + "## 指数和对数\n", + "\n", + "- `numpy.exp(x, *args, **kwargs)` Calculate the exponential of all elements in the input array.\n", + "- `numpy.log(x, *args, **kwargs)` Natural logarithm, element-wise.\n", + "- `numpy.exp2(x, *args, **kwargs)` Calculate `2**p` for all `p` in the input array.\n", + "- `numpy.log2(x, *args, **kwargs)` Base-2 logarithm of `x`.\n", + "- `numpy.log10(x, *args, **kwargs)` Return the base 10 logarithm of the input array, element-wise.\n", + "\n", + "\n", + "\n", + "\n", + "【例】The natural logarithm `log` is the inverse of the exponential function, so that `log(exp(x)) = x`. The natural logarithm is logarithm in base `e`.\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(1, 5)\n", + "print(x)\n", + "# [1 2 3 4]\n", + "y = np.exp(x)\n", + "print(y)\n", + "# [ 2.71828183 7.3890561 20.08553692 54.59815003]\n", + "z = np.log(y)\n", + "print(z)\n", + "# [1. 2. 3. 4.]\n", + "```\n", + "\n", + "\n", + "\n", + "---\n", + "## 加法函数、乘法函数\n", + "\n", + "- `numpy.sum(a[, axis=None, dtype=None, out=None, …])` Sum of array elements over a given axis.\n", + "\n", + "通过不同的 `axis`,numpy 会沿着不同的方向进行操作:如果不设置,那么对所有的元素操作;如果`axis=0`,则沿着纵轴进行操作;`axis=1`,则沿着横轴进行操作。但这只是简单的二位数组,如果是多维的呢?可以总结为一句话:设`axis=i`,则 numpy 沿着第`i`个下标变化的方向进行操作。\n", + "\n", + "- `numpy.cumsum(a, axis=None, dtype=None, out=None)` Return the cumulative sum of the elements along a given axis.\n", + "\n", + "**聚合函数** 是指对一组值(比如一个数组)进行操作,返回一个单一值作为结果的函数。因而,求数组所有元素之和的函数就是聚合函数。`ndarray`类实现了多个这样的函数。\n", + "\n", + "【例】返回给定轴上的数组元素的总和。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.sum(x)\n", + "print(y) # 575\n", + "\n", + "y = np.sum(x, axis=0)\n", + "print(y) # [105 110 115 120 125]\n", + "\n", + "y = np.sum(x, axis=1)\n", + "print(y) # [ 65 90 115 140 165]\n", + "```\n", + "\n", + "\n", + "【例】返回给定轴上的数组元素的累加和。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.cumsum(x)\n", + "print(y)\n", + "# [ 11 23 36 50 65 81 98 116 135 155 176 198 221 245 270 296 323 351\n", + "# 380 410 441 473 506 540 575]\n", + "\n", + "y = np.cumsum(x, axis=0)\n", + "print(y)\n", + "# [[ 11 12 13 14 15]\n", + "# [ 27 29 31 33 35]\n", + "# [ 48 51 54 57 60]\n", + "# [ 74 78 82 86 90]\n", + "# [105 110 115 120 125]]\n", + "\n", + "y = np.cumsum(x, axis=1)\n", + "print(y)\n", + "# [[ 11 23 36 50 65]\n", + "# [ 16 33 51 70 90]\n", + "# [ 21 43 66 90 115]\n", + "# [ 26 53 81 110 140]\n", + "# [ 31 63 96 130 165]]\n", + "```\n", + "\n", + "- `numpy.prod(a[, axis=None, dtype=None, out=None, …])` Return the product of array elements over a given axis.\n", + "\n", + "\n", + "- `numpy.cumprod(a, axis=None, dtype=None, out=None)` Return the cumulative product of elements along a given axis.\n", + "\n", + "【例】返回给定轴上数组元素的乘积。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.prod(x)\n", + "print(y) # 788529152\n", + "\n", + "y = np.prod(x, axis=0)\n", + "print(y)\n", + "# [2978976 3877632 4972968 6294624 7875000]\n", + "\n", + "y = np.prod(x, axis=1)\n", + "print(y)\n", + "# [ 360360 1860480 6375600 17100720 38955840]\n", + "```\n", + "\n", + "\n", + "【例】返回给定轴上数组元素的累乘。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.cumprod(x)\n", + "print(y)\n", + "# [ 11 132 1716 24024 360360 5765760\n", + "# 98017920 1764322560 -837609728 427674624 391232512 17180672\n", + "# 395155456 893796352 870072320 1147043840 905412608 -418250752\n", + "# 755630080 1194065920 -1638662144 -897581056 444596224 -2063597568\n", + "# 788529152]\n", + "\n", + "y = np.cumprod(x, axis=0)\n", + "print(y)\n", + "# [[ 11 12 13 14 15]\n", + "# [ 176 204 234 266 300]\n", + "# [ 3696 4488 5382 6384 7500]\n", + "# [ 96096 121176 150696 185136 225000]\n", + "# [2978976 3877632 4972968 6294624 7875000]]\n", + "\n", + "y = np.cumprod(x, axis=1)\n", + "print(y)\n", + "# [[ 11 132 1716 24024 360360]\n", + "# [ 16 272 4896 93024 1860480]\n", + "# [ 21 462 10626 255024 6375600]\n", + "# [ 26 702 19656 570024 17100720]\n", + "# [ 31 992 32736 1113024 38955840]]\n", + "```\n", + "\n", + "- `numpy.diff(a, n=1, axis=-1, prepend=np._NoValue, append=np._NoValue)` Calculate the n-th discrete difference along the given axis.\n", + " - a:输入矩阵\n", + " - n:可选,代表要执行几次差值\n", + " - axis:默认是最后一个\n", + "\n", + "\n", + "The first difference is given by `out[i] = a[i+1] - a[i]` along the given axis, higher differences are calculated by using `diff` recursively.\n", + "\n", + "【例】沿着指定轴计算第N维的离散差值。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.arange(2, 14).reshape((3, 4))\n", + "A[1, 1] = 8\n", + "print(A)\n", + "# [[ 2 3 4 5]\n", + "# [ 6 8 8 9]\n", + "# [10 11 12 13]]\n", + "print(np.diff(A))\n", + "# [[1 1 1]\n", + "# [2 0 1]\n", + "# [1 1 1]]\n", + "print(np.diff(A, axis=0))\n", + "# [[4 5 4 4]\n", + "# [4 3 4 4]]\n", + "```\n", + "\n", + "\n", + "\n", + "---\n", + "## 四舍五入\n", + "\n", + "- `numpy.around(a, decimals=0, out=None)` Evenly round to the given number of decimals.\n", + "\n", + "\n", + "【例】将数组舍入到给定的小数位数。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.random.rand(3, 3) * 10\n", + "print(x)\n", + "# [[6.59144457 3.78566113 8.15321227]\n", + "# [1.68241475 3.78753332 7.68886328]\n", + "# [2.84255822 9.58106727 7.86678037]]\n", + "\n", + "y = np.around(x)\n", + "print(y)\n", + "# [[ 7. 4. 8.]\n", + "# [ 2. 4. 8.]\n", + "# [ 3. 10. 8.]]\n", + "\n", + "y = np.around(x, decimals=2)\n", + "print(y)\n", + "# [[6.59 3.79 8.15]\n", + "# [1.68 3.79 7.69]\n", + "# [2.84 9.58 7.87]]\n", + "```\n", + "\n", + "- `numpy.ceil(x, *args, **kwargs)` Return the ceiling of the input, element-wise.\n", + "- `numpy.floor(x, *args, **kwargs)` Return the floor of the input, element-wise.\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.random.rand(3, 3) * 10\n", + "print(x)\n", + "# [[0.67847795 1.33073923 4.53920122]\n", + "# [7.55724676 5.88854047 2.65502046]\n", + "# [8.67640444 8.80110812 5.97528726]]\n", + "\n", + "y = np.ceil(x)\n", + "print(y)\n", + "# [[1. 2. 5.]\n", + "# [8. 6. 3.]\n", + "# [9. 9. 6.]]\n", + "\n", + "y = np.floor(x)\n", + "print(y)\n", + "# [[0. 1. 4.]\n", + "# [7. 5. 2.]\n", + "# [8. 8. 5.]]\n", + "```\n", + "\n", + "---\n", + "## 杂项\n", + "\n", + "- `numpy.clip(a, a_min, a_max, out=None, **kwargs):` Clip (limit) the values in an array.\n", + "\n", + "Given an interval, values outside the interval are clipped to the interval edges. For example, if an interval of `[0, 1]` is specified, values smaller than 0 become 0, and values larger than 1 become 1.\n", + "\n", + "\n", + "【例】裁剪(限制)数组中的值。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.clip(x, a_min=20, a_max=30)\n", + "print(y)\n", + "# [[20 20 20 20 20]\n", + "# [20 20 20 20 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [30 30 30 30 30]]\n", + "```\n", + "\n", + "\n", + "\n", + "- `numpy.absolute(x, *args, **kwargs)` Calculate the absolute value element-wise. \n", + "- `numpy.abs(x, *args, **kwargs)` is a shorthand for this function.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(-5, 5)\n", + "print(x)\n", + "# [-5 -4 -3 -2 -1 0 1 2 3 4]\n", + "\n", + "y = np.abs(x)\n", + "print(y)\n", + "# [5 4 3 2 1 0 1 2 3 4]\n", + "\n", + "y = np.absolute(x)\n", + "print(y)\n", + "# [5 4 3 2 1 0 1 2 3 4]\n", + "```\n", + "\n", + "- `numpy.sign(x, *args, **kwargs)` Returns an element-wise indication of the sign of a number.\n", + "\n", + "【例】\n", + "\n", + "```python\n", + "x = np.arange(-5, 5)\n", + "print(x)\n", + "#[-5 -4 -3 -2 -1 0 1 2 3 4]\n", + "print(np.sign(x))\n", + "#[-1 -1 -1 -1 -1 0 1 1 1 1]\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "---\n", + "**参考文献**\n", + "- https://mp.weixin.qq.com/s/RWsGvvmw4ptf7d8zPIDEJw\n", + "- https://blog.csdn.net/hanshuobest/article/details/78558826?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2020-08-30T17:00:33.199734Z", + "start_time": "2020-08-30T17:00:33.194782Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-5 -4 -3 -2 -1 0 1 2 3 4]\n", + "[-1 -1 -1 -1 -1 0 1 1 1 1]\n" + ] + } + ], + "source": [ + "x = np.arange(-5, 5)\n", + "print(x)\n", + "print(np.sign(x))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "307.2px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/08. 逻辑函数-checkpoint.ipynb b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/08. 逻辑函数-checkpoint.ipynb new file mode 100644 index 0000000..d3e7eeb --- /dev/null +++ b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/08. 逻辑函数-checkpoint.ipynb @@ -0,0 +1,502 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 逻辑函数\n", + "\n", + "## 真值测试\n", + "### numpy.all\n", + "### numpy.any\n", + "\n", + "- `numpy.all(a, axis=None, out=None, keepdims=np._NoValue)` Test whether all array elements along a given axis evaluate to True.\n", + "- `numpy.any(a, axis=None, out=None, keepdims=np._NoValue)` Test whether any array element along a given axis evaluates to True.\n", + "\n", + "\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.array([0, 4, 5])\n", + "b = np.copy(a)\n", + "print(np.all(a == b)) # True\n", + "print(np.any(a == b)) # True\n", + "\n", + "b[0] = 1\n", + "print(np.all(a == b)) # False\n", + "print(np.any(a == b)) # True\n", + "\n", + "print(np.all([1.0, np.nan])) # True\n", + "print(np.any([1.0, np.nan])) # True\n", + "\n", + "a = np.eye(3)\n", + "print(np.all(a, axis=0)) # [False False False]\n", + "print(np.any(a, axis=0)) # [ True True True]\n", + "```\n", + "\n", + "\n", + "---\n", + "## 数组内容\n", + "\n", + "- `numpy.isnan(x, *args, **kwargs)` Test element-wise for NaN and return result as a boolean array.\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "a=np.array([1,2,np.nan])\n", + "print(np.isnan(a))\n", + "#[False False True]\n", + "\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "---\n", + "## 逻辑运算\n", + "\n", + "- `numpy.logical_not(x, *args, **kwargs)`Compute the truth value of NOT x element-wise.\n", + "- `numpy.logical_and(x1, x2, *args, **kwargs)` Compute the truth value of x1 AND x2 element-wise.\n", + "- `numpy.logical_or(x1, x2, *args, **kwargs)`Compute the truth value of x1 OR x2 element-wise.\n", + "- `numpy.logical_xor(x1, x2, *args, **kwargs)`Compute the truth value of x1 XOR x2, element-wise.\n", + "\n", + "\n", + "\n", + "\n", + "```python\n", + "【例】计算非x元素的真值。\n", + "\n", + "import numpy as np\n", + "\n", + "print(np.logical_not(3)) \n", + "# False\n", + "print(np.logical_not([True, False, 0, 1]))\n", + "# [False True True False]\n", + "\n", + "x = np.arange(5)\n", + "print(np.logical_not(x < 3))\n", + "# [False False False True True]\n", + "\n", + "【例】计算x1 AND x2元素的真值。\n", + "\n", + "print(np.logical_and(True, False)) \n", + "# False\n", + "print(np.logical_and([True, False], [True, False]))\n", + "# [ True False]\n", + "print(np.logical_and(x > 1, x < 4))\n", + "# [False False True True False]\n", + "\n", + "【例】逐元素计算x1 OR x2的真值。\n", + "\n", + "\n", + "print(np.logical_or(True, False))\n", + "# True\n", + "print(np.logical_or([True, False], [False, False]))\n", + "# [ True False]\n", + "print(np.logical_or(x < 1, x > 3))\n", + "# [ True False False False True]\n", + "\n", + "【例】计算x1 XOR x2的真值,按元素计算。\n", + "\n", + "print(np.logical_xor(True, False))\n", + "# True\n", + "print(np.logical_xor([True, True, False, False], [True, False, True, False]))\n", + "# [False True True False]\n", + "print(np.logical_xor(x < 1, x > 3))\n", + "# [ True False False False True]\n", + "print(np.logical_xor(0, np.eye(2)))\n", + "# [[ True False]\n", + "# [False True]]\n", + "```\n", + "\n", + "\n", + "## 对照\n", + "\n", + "- `numpy.greater(x1, x2, *args, **kwargs)` Return the truth value of (x1 > x2) element-wise.\n", + "- `numpy.greater_equal(x1, x2, *args, **kwargs)` Return the truth value of (x1 >= x2) element-wise.\n", + "- `numpy.equal(x1, x2, *args, **kwargs)` Return (x1 == x2) element-wise.\n", + "- `numpy.not_equal(x1, x2, *args, **kwargs)` Return (x1 != x2) element-wise.\n", + "- `numpy.less(x1, x2, *args, **kwargs)` Return the truth value of (x1 < x2) element-wise.\n", + "- `numpy.less_equal(x1, x2, *args, **kwargs)` Return the truth value of (x1 =< x2) element-wise.\n", + "\n", + "\n", + "\n", + "【例】numpy对以上对照函数进行了运算符的重载。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "\n", + "y = x > 2\n", + "print(y)\n", + "print(np.greater(x, 2))\n", + "# [False False True True True True True True]\n", + "\n", + "y = x >= 2\n", + "print(y)\n", + "print(np.greater_equal(x, 2))\n", + "# [False True True True True True True True]\n", + "\n", + "y = x == 2\n", + "print(y)\n", + "print(np.equal(x, 2))\n", + "# [False True False False False False False False]\n", + "\n", + "y = x != 2\n", + "print(y)\n", + "print(np.not_equal(x, 2))\n", + "# [ True False True True True True True True]\n", + "\n", + "y = x < 2\n", + "print(y)\n", + "print(np.less(x, 2))\n", + "# [ True False False False False False False False]\n", + "\n", + "y = x <= 2\n", + "print(y)\n", + "print(np.less_equal(x, 2))\n", + "# [ True True False False False False False False]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x > 20\n", + "print(y)\n", + "print(np.greater(x, 20))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]]\n", + "\n", + "y = x >= 20\n", + "print(y)\n", + "print(np.greater_equal(x, 20))\n", + "# [[False False False False False]\n", + "# [False False False False True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]]\n", + "\n", + "y = x == 20\n", + "print(y)\n", + "print(np.equal(x, 20))\n", + "# [[False False False False False]\n", + "# [False False False False True]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]]\n", + "\n", + "y = x != 20\n", + "print(y)\n", + "print(np.not_equal(x, 20))\n", + "# [[ True True True True True]\n", + "# [ True True True True False]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]]\n", + "\n", + "\n", + "y = x < 20\n", + "print(y)\n", + "print(np.less(x, 20))\n", + "# [[ True True True True True]\n", + "# [ True True True True False]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]]\n", + "\n", + "y = x <= 20\n", + "print(y)\n", + "print(np.less_equal(x, 20))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200611)\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = np.random.randint(10, 40, [5, 5])\n", + "print(y)\n", + "# [[32 28 31 33 37]\n", + "# [23 37 37 30 29]\n", + "# [32 24 10 33 15]\n", + "# [27 17 10 36 16]\n", + "# [25 32 23 39 34]]\n", + "\n", + "z = x > y\n", + "print(z)\n", + "print(np.greater(x, y))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [False False True False True]\n", + "# [False True True False True]\n", + "# [ True False True False True]]\n", + "\n", + "z = x >= y\n", + "print(z)\n", + "print(np.greater_equal(x, y))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [False False True False True]\n", + "# [False True True False True]\n", + "# [ True True True False True]]\n", + "\n", + "z = x == y\n", + "print(z)\n", + "print(np.equal(x, y))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False True False False False]]\n", + "\n", + "z = x != y\n", + "print(z)\n", + "print(np.not_equal(x, y))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True False True True True]]\n", + "\n", + "z = x < y\n", + "print(z)\n", + "print(np.less(x, y))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True False True False]\n", + "# [ True False False True False]\n", + "# [False False False True False]]\n", + "\n", + "z = x <= y\n", + "print(z)\n", + "print(np.less_equal(x, y))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True False True False]\n", + "# [ True False False True False]\n", + "# [False True False True False]]\n", + "```\n", + "\n", + "【例】注意 numpy 的广播规则。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "np.random.seed(20200611)\n", + "y = np.random.randint(10, 50, 5)\n", + "\n", + "print(y)\n", + "# [32 37 30 24 10]\n", + "\n", + "z = x > y\n", + "print(z)\n", + "print(np.greater(x, y))\n", + "# [[False False False False True]\n", + "# [False False False False True]\n", + "# [False False False False True]\n", + "# [False False False True True]\n", + "# [False False True True True]]\n", + "\n", + "z = x >= y\n", + "print(z)\n", + "print(np.greater_equal(x, y))\n", + "# [[False False False False True]\n", + "# [False False False False True]\n", + "# [False False False True True]\n", + "# [False False False True True]\n", + "# [False False True True True]]\n", + "\n", + "z = x == y\n", + "print(z)\n", + "print(np.equal(x, y))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [False False False True False]\n", + "# [False False False False False]\n", + "# [False False False False False]]\n", + "\n", + "z = x != y\n", + "print(z)\n", + "print(np.not_equal(x, y))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True False True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]]\n", + "\n", + "z = x < y\n", + "print(z)\n", + "print(np.less(x, y))\n", + "# [[ True True True True False]\n", + "# [ True True True True False]\n", + "# [ True True True False False]\n", + "# [ True True True False False]\n", + "# [ True True False False False]]\n", + "\n", + "z = x <= y\n", + "print(z)\n", + "print(np.less_equal(x, y))\n", + "# [[ True True True True False]\n", + "# [ True True True True False]\n", + "# [ True True True True False]\n", + "# [ True True True False False]\n", + "# [ True True False False False]]\n", + "```\n", + "\n", + "\n", + "- `numpy.isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False)` Returns a boolean array where two arrays are element-wise equal within a tolerance.\n", + "- `numpy.allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False)` Returns True if two arrays are element-wise equal within a tolerance. \n", + "\n", + "`numpy.allclose()` 等价于 `numpy.all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan))`。\n", + "\n", + "The tolerance values are positive, typically very small numbers. The relative difference (`rtol * abs(b)`) and the absolute difference `atol` are added together to compare against the absolute difference between `a` and `b`.\n", + "\n", + "判断是否为True的计算依据:\n", + "\n", + "```python\n", + "np.absolute(a - b) <= (atol + rtol * absolute(b))\n", + "\n", + "- atol:float,绝对公差。\n", + "- rtol:float,相对公差。\n", + "```\n", + "\n", + "NaNs are treated as equal if they are in the same place and if `equal_nan=True`. Infs are treated as equal if they are in the same place and of the same sign in both arrays.\n", + "\n", + "【例】比较两个数组是否可以认为相等。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.isclose([1e10, 1e-7], [1.00001e10, 1e-8])\n", + "print(x) # [ True False]\n", + "\n", + "x = np.allclose([1e10, 1e-7], [1.00001e10, 1e-8])\n", + "print(x) # False\n", + "\n", + "x = np.isclose([1e10, 1e-8], [1.00001e10, 1e-9])\n", + "print(x) # [ True True]\n", + "\n", + "x = np.allclose([1e10, 1e-8], [1.00001e10, 1e-9])\n", + "print(x) # True\n", + "\n", + "x = np.isclose([1e10, 1e-8], [1.0001e10, 1e-9])\n", + "print(x) # [False True]\n", + "\n", + "x = np.allclose([1e10, 1e-8], [1.0001e10, 1e-9])\n", + "print(x) # False\n", + "\n", + "x = np.isclose([1.0, np.nan], [1.0, np.nan])\n", + "print(x) # [ True False]\n", + "\n", + "x = np.allclose([1.0, np.nan], [1.0, np.nan])\n", + "print(x) # False\n", + "\n", + "x = np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)\n", + "print(x) # [ True True]\n", + "\n", + "x = np.allclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)\n", + "print(x) # True\n", + "```\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/练习--数学函数,逻辑函数-checkpoint.ipynb b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/练习--数学函数,逻辑函数-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/练习--数学函数,逻辑函数-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/练习--数学函数,逻辑函数-答案-checkpoint.ipynb b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/练习--数学函数,逻辑函数-答案-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/.ipynb_checkpoints/练习--数学函数,逻辑函数-答案-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/07. 数学函数.ipynb b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/07. 数学函数.ipynb new file mode 100644 index 0000000..70a02c3 --- /dev/null +++ b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/07. 数学函数.ipynb @@ -0,0 +1,851 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 向量化和广播\n", + "\n", + "向量化和广播这两个概念是 numpy 内部实现的基础。有了向量化,编写代码时无需使用显式循环。这些循环实际上不能省略,只不过是在内部实现,被代码中的其他结构代替。向量化的应用使得代码更简洁,可读性更强,也可以说使用了向量化方法的代码看上去更“Pythonic”。\n", + "\n", + "广播(Broadcasting)机制描述了 numpy 如何在算术运算期间处理具有不同形状的数组,让较小的数组在较大的数组上“广播”,以便它们具有兼容的形状。并不是所有的维度都要彼此兼容才符合广播机制的要求,但它们必须满足一定的条件。\n", + "\n", + "若两个数组的各维度兼容,也就是两个数组的每一维等长,或其中一个数组为 一维,那么广播机制就适用。如果这两个条件不满足,numpy就会抛出异常,说两个数组不兼容。\n", + "\n", + "总结来说,广播的规则有三个:\n", + "- 如果两个数组的维度数dim不相同,那么小维度数组的形状将会在左边补1。\n", + "- 如果shape维度不匹配,但是有维度是1,那么可以扩展维度是1的维度匹配另一个数组;\n", + "- 如果shape维度不匹配,但是没有任何一个维度是1,则匹配引发错误;\n", + "\n", + "【例】二维数组加一维数组\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(4)\n", + "y = np.ones((3, 4))\n", + "print(x.shape) # (4,)\n", + "print(y.shape) # (3, 4)\n", + "\n", + "print((x + y).shape) # (3, 4)\n", + "print(x + y)\n", + "# [[1. 2. 3. 4.]\n", + "# [1. 2. 3. 4.]\n", + "# [1. 2. 3. 4.]]\n", + "```\n", + "\n", + "\n", + "【例】两个数组均需要广播\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(4).reshape(4, 1)\n", + "y = np.ones(5)\n", + "\n", + "print(x.shape) # (4, 1)\n", + "print(y.shape) # (5,)\n", + "\n", + "print((x + y).shape) # (4, 5)\n", + "print(x + y)\n", + "# [[1. 1. 1. 1. 1.]\n", + "# [2. 2. 2. 2. 2.]\n", + "# [3. 3. 3. 3. 3.]\n", + "# [4. 4. 4. 4. 4.]]\n", + "\n", + "x = np.array([0.0, 10.0, 20.0, 30.0])\n", + "y = np.array([1.0, 2.0, 3.0])\n", + "z = x[:, np.newaxis] + y\n", + "print(z)\n", + "# [[ 1. 2. 3.]\n", + "# [11. 12. 13.]\n", + "# [21. 22. 23.]\n", + "# [31. 32. 33.]]\n", + "```\n", + "\n", + "【例】不匹配报错的例子\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(4)\n", + "y = np.ones(5)\n", + "\n", + "print(x.shape) # (4,)\n", + "print(y.shape) # (5,)\n", + "\n", + "print(x + y)\n", + "# ValueError: operands could not be broadcast together with shapes (4,) (5,) \n", + "```\n", + "\n", + "\n", + "---\n", + "# 数学函数\n", + "\n", + "\n", + "## 算数运算\n", + "### numpy.add\n", + "### numpy.subtract\n", + "### numpy.multiply\n", + "### numpy.divide\n", + "### numpy.floor_divide\n", + "### numpy.power\n", + "- `numpy.add(x1, x2, *args, **kwargs)` Add arguments element-wise.\n", + "- `numpy.subtract(x1, x2, *args, **kwargs)` Subtract arguments element-wise.\n", + "- `numpy.multiply(x1, x2, *args, **kwargs)` Multiply arguments element-wise.\n", + "- `numpy.divide(x1, x2, *args, **kwargs)` Returns a true division of the inputs, element-wise.\n", + "- `numpy.floor_divide(x1, x2, *args, **kwargs)` Return the largest integer smaller or equal to the division of the inputs.\n", + "- `numpy.power(x1, x2, *args, **kwargs)` First array elements raised to powers from second array, element-wise.\n", + "\n", + "在 numpy 中对以上函数进行了运算符的重载,且运算符为 **元素级**。也就是说,它们只用于位置相同的元素之间,所得到的运算结果组成一个新的数组。\n", + "\n", + "【例】注意 numpy 的广播规则。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "y = x + 1\n", + "print(y)\n", + "print(np.add(x, 1))\n", + "# [2 3 4 5 6 7 8 9]\n", + "\n", + "y = x - 1\n", + "print(y)\n", + "print(np.subtract(x, 1))\n", + "# [0 1 2 3 4 5 6 7]\n", + "\n", + "y = x * 2\n", + "print(y)\n", + "print(np.multiply(x, 2))\n", + "# [ 2 4 6 8 10 12 14 16]\n", + "\n", + "y = x / 2\n", + "print(y)\n", + "print(np.divide(x, 2))\n", + "# [0.5 1. 1.5 2. 2.5 3. 3.5 4. ]\n", + "\n", + "y = x // 2\n", + "print(y)\n", + "print(np.floor_divide(x, 2))\n", + "# [0 1 1 2 2 3 3 4]\n", + "\n", + "y = x ** 2\n", + "print(y)\n", + "print(np.power(x, 2))\n", + "# [ 1 4 9 16 25 36 49 64]\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "【例】注意 numpy 的广播规则。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x + 1\n", + "print(y)\n", + "print(np.add(x, 1))\n", + "# [[12 13 14 15 16]\n", + "# [17 18 19 20 21]\n", + "# [22 23 24 25 26]\n", + "# [27 28 29 30 31]\n", + "# [32 33 34 35 36]]\n", + "\n", + "y = x - 1\n", + "print(y)\n", + "print(np.subtract(x, 1))\n", + "# [[10 11 12 13 14]\n", + "# [15 16 17 18 19]\n", + "# [20 21 22 23 24]\n", + "# [25 26 27 28 29]\n", + "# [30 31 32 33 34]]\n", + "\n", + "y = x * 2\n", + "print(y)\n", + "print(np.multiply(x, 2))\n", + "# [[22 24 26 28 30]\n", + "# [32 34 36 38 40]\n", + "# [42 44 46 48 50]\n", + "# [52 54 56 58 60]\n", + "# [62 64 66 68 70]]\n", + "\n", + "y = x / 2\n", + "print(y)\n", + "print(np.divide(x, 2))\n", + "# [[ 5.5 6. 6.5 7. 7.5]\n", + "# [ 8. 8.5 9. 9.5 10. ]\n", + "# [10.5 11. 11.5 12. 12.5]\n", + "# [13. 13.5 14. 14.5 15. ]\n", + "# [15.5 16. 16.5 17. 17.5]]\n", + "\n", + "y = x // 2\n", + "print(y)\n", + "print(np.floor_divide(x, 2))\n", + "# [[ 5 6 6 7 7]\n", + "# [ 8 8 9 9 10]\n", + "# [10 11 11 12 12]\n", + "# [13 13 14 14 15]\n", + "# [15 16 16 17 17]]\n", + "\n", + "y = x ** 2\n", + "print(y)\n", + "print(np.power(x, 2))\n", + "# [[ 121 144 169 196 225]\n", + "# [ 256 289 324 361 400]\n", + "# [ 441 484 529 576 625]\n", + "# [ 676 729 784 841 900]\n", + "# [ 961 1024 1089 1156 1225]]\n", + "```\n", + "\n", + "【例】注意 numpy 的广播规则。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = np.arange(1, 6)\n", + "print(y)\n", + "# [1 2 3 4 5]\n", + "\n", + "z = x + y\n", + "print(z)\n", + "print(np.add(x, y))\n", + "# [[12 14 16 18 20]\n", + "# [17 19 21 23 25]\n", + "# [22 24 26 28 30]\n", + "# [27 29 31 33 35]\n", + "# [32 34 36 38 40]]\n", + "\n", + "z = x - y\n", + "print(z)\n", + "print(np.subtract(x, y))\n", + "# [[10 10 10 10 10]\n", + "# [15 15 15 15 15]\n", + "# [20 20 20 20 20]\n", + "# [25 25 25 25 25]\n", + "# [30 30 30 30 30]]\n", + "\n", + "z = x * y\n", + "print(z)\n", + "print(np.multiply(x, y))\n", + "# [[ 11 24 39 56 75]\n", + "# [ 16 34 54 76 100]\n", + "# [ 21 44 69 96 125]\n", + "# [ 26 54 84 116 150]\n", + "# [ 31 64 99 136 175]]\n", + "\n", + "z = x / y\n", + "print(z)\n", + "print(np.divide(x, y))\n", + "# [[11. 6. 4.33333333 3.5 3. ]\n", + "# [16. 8.5 6. 4.75 4. ]\n", + "# [21. 11. 7.66666667 6. 5. ]\n", + "# [26. 13.5 9.33333333 7.25 6. ]\n", + "# [31. 16. 11. 8.5 7. ]]\n", + "\n", + "z = x // y\n", + "print(z)\n", + "print(np.floor_divide(x, y))\n", + "# [[11 6 4 3 3]\n", + "# [16 8 6 4 4]\n", + "# [21 11 7 6 5]\n", + "# [26 13 9 7 6]\n", + "# [31 16 11 8 7]]\n", + "\n", + "z = x ** np.full([1, 5], 2)\n", + "print(z)\n", + "print(np.power(x, np.full([5, 5], 2)))\n", + "# [[ 121 144 169 196 225]\n", + "# [ 256 289 324 361 400]\n", + "# [ 441 484 529 576 625]\n", + "# [ 676 729 784 841 900]\n", + "# [ 961 1024 1089 1156 1225]]\n", + "```\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = np.arange(1, 26).reshape([5, 5])\n", + "print(y)\n", + "# [[ 1 2 3 4 5]\n", + "# [ 6 7 8 9 10]\n", + "# [11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]]\n", + "\n", + "z = x + y\n", + "print(z)\n", + "print(np.add(x, y))\n", + "# [[12 14 16 18 20]\n", + "# [22 24 26 28 30]\n", + "# [32 34 36 38 40]\n", + "# [42 44 46 48 50]\n", + "# [52 54 56 58 60]]\n", + "\n", + "z = x - y\n", + "print(z)\n", + "print(np.subtract(x, y))\n", + "# [[10 10 10 10 10]\n", + "# [10 10 10 10 10]\n", + "# [10 10 10 10 10]\n", + "# [10 10 10 10 10]\n", + "# [10 10 10 10 10]]\n", + "\n", + "z = x * y\n", + "print(z)\n", + "print(np.multiply(x, y))\n", + "# [[ 11 24 39 56 75]\n", + "# [ 96 119 144 171 200]\n", + "# [231 264 299 336 375]\n", + "# [416 459 504 551 600]\n", + "# [651 704 759 816 875]]\n", + "\n", + "z = x / y\n", + "print(z)\n", + "print(np.divide(x, y))\n", + "# [[11. 6. 4.33333333 3.5 3. ]\n", + "# [ 2.66666667 2.42857143 2.25 2.11111111 2. ]\n", + "# [ 1.90909091 1.83333333 1.76923077 1.71428571 1.66666667]\n", + "# [ 1.625 1.58823529 1.55555556 1.52631579 1.5 ]\n", + "# [ 1.47619048 1.45454545 1.43478261 1.41666667 1.4 ]]\n", + "\n", + "z = x // y\n", + "print(z)\n", + "print(np.floor_divide(x, y))\n", + "# [[11 6 4 3 3]\n", + "# [ 2 2 2 2 2]\n", + "# [ 1 1 1 1 1]\n", + "# [ 1 1 1 1 1]\n", + "# [ 1 1 1 1 1]]\n", + "\n", + "z = x ** np.full([5, 5], 2)\n", + "print(z)\n", + "print(np.power(x, np.full([5, 5], 2)))\n", + "# [[ 121 144 169 196 225]\n", + "# [ 256 289 324 361 400]\n", + "# [ 441 484 529 576 625]\n", + "# [ 676 729 784 841 900]\n", + "# [ 961 1024 1089 1156 1225]]\n", + "```\n", + "\n", + "### numpy.sqrt\n", + "### numpy.square\n", + "- `numpy.sqrt(x, *args, **kwargs)` Return the non-negative square-root of an array, element-wise.\n", + "- `numpy.square(x, *args, **kwargs)` Return the element-wise square of the input.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(1, 5)\n", + "print(x) # [1 2 3 4]\n", + "\n", + "y = np.sqrt(x)\n", + "print(y)\n", + "# [1. 1.41421356 1.73205081 2. ]\n", + "print(np.power(x, 0.5))\n", + "# [1. 1.41421356 1.73205081 2. ]\n", + "\n", + "y = np.square(x)\n", + "print(y)\n", + "# [ 1 4 9 16]\n", + "print(np.power(x, 2))\n", + "# [ 1 4 9 16]\n", + "```\n", + "\n", + "\n", + "---\n", + "## 三角函数\n", + "\n", + "### numpy.sin\n", + "### numpy.cos\n", + "### numpy.tan\n", + "### numpy.arcsin\n", + "### numpy.arccos\n", + "### numpy.arctan\n", + "\n", + "- `numpy.sin(x, *args, **kwargs)` Trigonometric sine, element-wise.\n", + "- `numpy.cos(x, *args, **kwargs)` Cosine element-wise.\n", + "- `numpy.tan(x, *args, **kwargs)` Compute tangent element-wise.\n", + "- `numpy.arcsin(x, *args, **kwargs)` Inverse sine, element-wise.\n", + "- `numpy.arccos(x, *args, **kwargs)` Trigonometric inverse cosine, element-wise.\n", + "- `numpy.arctan(x, *args, **kwargs)` Trigonometric inverse tangent, element-wise.\n", + "\n", + "\n", + "**通用函数**(universal function)通常叫作ufunc,它对数组中的各个元素逐一进行操作。这表明,通用函数分别处理输入数组的每个元素,生成的结果组成一个新的输出数组。输出数组的大小跟输入数组相同。\n", + "\n", + "三角函数等很多数学运算符合通用函数的定义,例如,计算平方根的`sqrt()`函数、用来取对数的`log()`函数和求正弦值的`sin()`函数。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.linspace(start=0, stop=np.pi / 2, num=10)\n", + "print(x)\n", + "# [0. 0.17453293 0.34906585 0.52359878 0.6981317 0.87266463\n", + "# 1.04719755 1.22173048 1.3962634 1.57079633]\n", + "\n", + "y = np.sin(x)\n", + "print(y)\n", + "# [0. 0.17364818 0.34202014 0.5 0.64278761 0.76604444\n", + "# 0.8660254 0.93969262 0.98480775 1. ]\n", + "\n", + "z = np.arcsin(y)\n", + "print(z)\n", + "# [0. 0.17453293 0.34906585 0.52359878 0.6981317 0.87266463\n", + "# 1.04719755 1.22173048 1.3962634 1.57079633]\n", + "\n", + "y = np.cos(x)\n", + "print(y)\n", + "# [1.00000000e+00 9.84807753e-01 9.39692621e-01 8.66025404e-01\n", + "# 7.66044443e-01 6.42787610e-01 5.00000000e-01 3.42020143e-01\n", + "# 1.73648178e-01 6.12323400e-17]\n", + "\n", + "z = np.arccos(y)\n", + "print(z)\n", + "# [0. 0.17453293 0.34906585 0.52359878 0.6981317 0.87266463\n", + "# 1.04719755 1.22173048 1.3962634 1.57079633]\n", + "\n", + "y = np.tan(x)\n", + "print(y)\n", + "# [0.00000000e+00 1.76326981e-01 3.63970234e-01 5.77350269e-01\n", + "# 8.39099631e-01 1.19175359e+00 1.73205081e+00 2.74747742e+00\n", + "# 5.67128182e+00 1.63312394e+16]\n", + "\n", + "z = np.arctan(y)\n", + "print(z)\n", + "# [0. 0.17453293 0.34906585 0.52359878 0.6981317 0.87266463\n", + "# 1.04719755 1.22173048 1.3962634 1.57079633]\n", + "```\n", + "\n", + "---\n", + "## 指数和对数\n", + "### numpy.exp\n", + "### numpy.log\n", + "### numpy.exp2\n", + "### numpy.log2\n", + "### numpy.log10\n", + "\n", + "- `numpy.exp(x, *args, **kwargs)` Calculate the exponential of all elements in the input array.\n", + "- `numpy.log(x, *args, **kwargs)` Natural logarithm, element-wise.\n", + "- `numpy.exp2(x, *args, **kwargs)` Calculate `2**p` for all `p` in the input array.\n", + "- `numpy.log2(x, *args, **kwargs)` Base-2 logarithm of `x`.\n", + "- `numpy.log10(x, *args, **kwargs)` Return the base 10 logarithm of the input array, element-wise.\n", + "\n", + "\n", + "\n", + "\n", + "【例】The natural logarithm `log` is the inverse of the exponential function, so that `log(exp(x)) = x`. The natural logarithm is logarithm in base `e`.\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(1, 5)\n", + "print(x)\n", + "# [1 2 3 4]\n", + "y = np.exp(x)\n", + "print(y)\n", + "# [ 2.71828183 7.3890561 20.08553692 54.59815003]\n", + "z = np.log(y)\n", + "print(z)\n", + "# [1. 2. 3. 4.]\n", + "```\n", + "\n", + "\n", + "\n", + "---\n", + "## 加法函数、乘法函数\n", + "### numpy.sum\n", + "\n", + "- `numpy.sum(a[, axis=None, dtype=None, out=None, …])` Sum of array elements over a given axis.\n", + "\n", + "通过不同的 `axis`,numpy 会沿着不同的方向进行操作:如果不设置,那么对所有的元素操作;如果`axis=0`,则沿着纵轴进行操作;`axis=1`,则沿着横轴进行操作。但这只是简单的二位数组,如果是多维的呢?可以总结为一句话:设`axis=i`,则 numpy 沿着第`i`个下标变化的方向进行操作。\n", + "\n", + "### numpy.cumsum\n", + "\n", + "- `numpy.cumsum(a, axis=None, dtype=None, out=None)` Return the cumulative sum of the elements along a given axis.\n", + "\n", + "**聚合函数** 是指对一组值(比如一个数组)进行操作,返回一个单一值作为结果的函数。因而,求数组所有元素之和的函数就是聚合函数。`ndarray`类实现了多个这样的函数。\n", + "\n", + "【例】返回给定轴上的数组元素的总和。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.sum(x)\n", + "print(y) # 575\n", + "\n", + "y = np.sum(x, axis=0)\n", + "print(y) # [105 110 115 120 125]\n", + "\n", + "y = np.sum(x, axis=1)\n", + "print(y) # [ 65 90 115 140 165]\n", + "```\n", + "\n", + "\n", + "【例】返回给定轴上的数组元素的累加和。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.cumsum(x)\n", + "print(y)\n", + "# [ 11 23 36 50 65 81 98 116 135 155 176 198 221 245 270 296 323 351\n", + "# 380 410 441 473 506 540 575]\n", + "\n", + "y = np.cumsum(x, axis=0)\n", + "print(y)\n", + "# [[ 11 12 13 14 15]\n", + "# [ 27 29 31 33 35]\n", + "# [ 48 51 54 57 60]\n", + "# [ 74 78 82 86 90]\n", + "# [105 110 115 120 125]]\n", + "\n", + "y = np.cumsum(x, axis=1)\n", + "print(y)\n", + "# [[ 11 23 36 50 65]\n", + "# [ 16 33 51 70 90]\n", + "# [ 21 43 66 90 115]\n", + "# [ 26 53 81 110 140]\n", + "# [ 31 63 96 130 165]]\n", + "```\n", + "### numpy.prod 乘积\n", + "- `numpy.prod(a[, axis=None, dtype=None, out=None, …])` Return the product of array elements over a given axis.\n", + "\n", + "### numpy.cumprod 累乘\n", + "- `numpy.cumprod(a, axis=None, dtype=None, out=None)` Return the cumulative product of elements along a given axis.\n", + "\n", + "【例】返回给定轴上数组元素的乘积。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.prod(x)\n", + "print(y) # 788529152\n", + "\n", + "y = np.prod(x, axis=0)\n", + "print(y)\n", + "# [2978976 3877632 4972968 6294624 7875000]\n", + "\n", + "y = np.prod(x, axis=1)\n", + "print(y)\n", + "# [ 360360 1860480 6375600 17100720 38955840]\n", + "```\n", + "\n", + "\n", + "【例】返回给定轴上数组元素的累乘。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.cumprod(x)\n", + "print(y)\n", + "# [ 11 132 1716 24024 360360 5765760\n", + "# 98017920 1764322560 -837609728 427674624 391232512 17180672\n", + "# 395155456 893796352 870072320 1147043840 905412608 -418250752\n", + "# 755630080 1194065920 -1638662144 -897581056 444596224 -2063597568\n", + "# 788529152]\n", + "\n", + "y = np.cumprod(x, axis=0)\n", + "print(y)\n", + "# [[ 11 12 13 14 15]\n", + "# [ 176 204 234 266 300]\n", + "# [ 3696 4488 5382 6384 7500]\n", + "# [ 96096 121176 150696 185136 225000]\n", + "# [2978976 3877632 4972968 6294624 7875000]]\n", + "\n", + "y = np.cumprod(x, axis=1)\n", + "print(y)\n", + "# [[ 11 132 1716 24024 360360]\n", + "# [ 16 272 4896 93024 1860480]\n", + "# [ 21 462 10626 255024 6375600]\n", + "# [ 26 702 19656 570024 17100720]\n", + "# [ 31 992 32736 1113024 38955840]]\n", + "```\n", + "### numpy.diff 差值\n", + "\n", + "- `numpy.diff(a, n=1, axis=-1, prepend=np._NoValue, append=np._NoValue)` Calculate the n-th discrete difference along the given axis.\n", + " - a:输入矩阵\n", + " - n:可选,代表要执行几次差值\n", + " - axis:默认是最后一个\n", + "\n", + "\n", + "The first difference is given by `out[i] = a[i+1] - a[i]` along the given axis, higher differences are calculated by using `diff` recursively.\n", + "\n", + "【例】沿着指定轴计算第N维的离散差值。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.arange(2, 14).reshape((3, 4))\n", + "A[1, 1] = 8\n", + "print(A)\n", + "# [[ 2 3 4 5]\n", + "# [ 6 8 8 9]\n", + "# [10 11 12 13]]\n", + "print(np.diff(A))\n", + "# [[1 1 1]\n", + "# [2 0 1]\n", + "# [1 1 1]]\n", + "print(np.diff(A, axis=0))\n", + "# [[4 5 4 4]\n", + "# [4 3 4 4]]\n", + "```\n", + "\n", + "\n", + "\n", + "---\n", + "## 四舍五入\n", + "### numpy.around 舍入\n", + "\n", + "- `numpy.around(a, decimals=0, out=None)` Evenly round to the given number of decimals.\n", + "\n", + "\n", + "【例】将数组舍入到给定的小数位数。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.random.rand(3, 3) * 10\n", + "print(x)\n", + "# [[6.59144457 3.78566113 8.15321227]\n", + "# [1.68241475 3.78753332 7.68886328]\n", + "# [2.84255822 9.58106727 7.86678037]]\n", + "\n", + "y = np.around(x)\n", + "print(y)\n", + "# [[ 7. 4. 8.]\n", + "# [ 2. 4. 8.]\n", + "# [ 3. 10. 8.]]\n", + "\n", + "y = np.around(x, decimals=2)\n", + "print(y)\n", + "# [[6.59 3.79 8.15]\n", + "# [1.68 3.79 7.69]\n", + "# [2.84 9.58 7.87]]\n", + "```\n", + "### numpy.ceil 上限\n", + "### numpy.floor 下限\n", + "\n", + "- `numpy.ceil(x, *args, **kwargs)` Return the ceiling of the input, element-wise.\n", + "- `numpy.floor(x, *args, **kwargs)` Return the floor of the input, element-wise.\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.random.rand(3, 3) * 10\n", + "print(x)\n", + "# [[0.67847795 1.33073923 4.53920122]\n", + "# [7.55724676 5.88854047 2.65502046]\n", + "# [8.67640444 8.80110812 5.97528726]]\n", + "\n", + "y = np.ceil(x)\n", + "print(y)\n", + "# [[1. 2. 5.]\n", + "# [8. 6. 3.]\n", + "# [9. 9. 6.]]\n", + "\n", + "y = np.floor(x)\n", + "print(y)\n", + "# [[0. 1. 4.]\n", + "# [7. 5. 2.]\n", + "# [8. 8. 5.]]\n", + "```\n", + "\n", + "---\n", + "## 杂项\n", + "\n", + "### numpy.clip 裁剪\n", + "\n", + "- `numpy.clip(a, a_min, a_max, out=None, **kwargs):` Clip (limit) the values in an array.\n", + "\n", + "Given an interval, values outside the interval are clipped to the interval edges. For example, if an interval of `[0, 1]` is specified, values smaller than 0 become 0, and values larger than 1 become 1.\n", + "\n", + "\n", + "【例】裁剪(限制)数组中的值。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.clip(x, a_min=20, a_max=30)\n", + "print(y)\n", + "# [[20 20 20 20 20]\n", + "# [20 20 20 20 20]\n", + "# [21 22 23 24 25]\n", + "# [26 27 28 29 30]\n", + "# [30 30 30 30 30]]\n", + "```\n", + "### numpy.absolute 绝对值\n", + "### numpy.abs\n", + "\n", + "- `numpy.absolute(x, *args, **kwargs)` Calculate the absolute value element-wise. \n", + "- `numpy.abs(x, *args, **kwargs)` is a shorthand for this function.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(-5, 5)\n", + "print(x)\n", + "# [-5 -4 -3 -2 -1 0 1 2 3 4]\n", + "\n", + "y = np.abs(x)\n", + "print(y)\n", + "# [5 4 3 2 1 0 1 2 3 4]\n", + "\n", + "y = np.absolute(x)\n", + "print(y)\n", + "# [5 4 3 2 1 0 1 2 3 4]\n", + "```\n", + "### numpy.sign 返回数字符号的逐元素指示\n", + "- `numpy.sign(x, *args, **kwargs)` Returns an element-wise indication of the sign of a number.\n", + "\n", + "【例】\n", + "\n", + "```python\n", + "x = np.arange(-5, 5)\n", + "print(x)\n", + "#[-5 -4 -3 -2 -1 0 1 2 3 4]\n", + "print(np.sign(x))\n", + "#[-1 -1 -1 -1 -1 0 1 1 1 1]\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "---\n", + "**参考文献**\n", + "- https://mp.weixin.qq.com/s/RWsGvvmw4ptf7d8zPIDEJw\n", + "- https://blog.csdn.net/hanshuobest/article/details/78558826?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2020-08-30T17:00:33.199734Z", + "start_time": "2020-08-30T17:00:33.194782Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-5 -4 -3 -2 -1 0 1 2 3 4]\n", + "[-1 -1 -1 -1 -1 0 1 1 1 1]\n" + ] + } + ], + "source": [ + "x = np.arange(-5, 5)\n", + "print(x)\n", + "print(np.sign(x))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "307.2px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/08. 逻辑函数.ipynb b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/08. 逻辑函数.ipynb new file mode 100644 index 0000000..5103fb2 --- /dev/null +++ b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/08. 逻辑函数.ipynb @@ -0,0 +1,516 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 逻辑函数\n", + "\n", + "## 真值测试\n", + "### numpy.all\n", + "### numpy.any\n", + "\n", + "- `numpy.all(a, axis=None, out=None, keepdims=np._NoValue)` Test whether all array elements along a given axis evaluate to True.\n", + "- `numpy.any(a, axis=None, out=None, keepdims=np._NoValue)` Test whether any array element along a given axis evaluates to True.\n", + "\n", + "\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.array([0, 4, 5])\n", + "b = np.copy(a)\n", + "print(np.all(a == b)) # True\n", + "print(np.any(a == b)) # True\n", + "\n", + "b[0] = 1\n", + "print(np.all(a == b)) # False\n", + "print(np.any(a == b)) # True\n", + "\n", + "print(np.all([1.0, np.nan])) # True\n", + "print(np.any([1.0, np.nan])) # True\n", + "\n", + "a = np.eye(3)\n", + "print(np.all(a, axis=0)) # [False False False]\n", + "print(np.any(a, axis=0)) # [ True True True]\n", + "```\n", + "\n", + "\n", + "---\n", + "## 数组内容\n", + "### numpy.isnan\n", + "\n", + "- `numpy.isnan(x, *args, **kwargs)` Test element-wise for NaN and return result as a boolean array.\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "a=np.array([1,2,np.nan])\n", + "print(np.isnan(a))\n", + "#[False False True]\n", + "\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "---\n", + "## 逻辑运算\n", + "### numpy.logical_not\n", + "### numpy.logical_and\n", + "### numpy.logical_or\n", + "### numpy.logical_xor\n", + "\n", + "\n", + "- `numpy.logical_not(x, *args, **kwargs)`Compute the truth value of NOT x element-wise.\n", + "- `numpy.logical_and(x1, x2, *args, **kwargs)` Compute the truth value of x1 AND x2 element-wise.\n", + "- `numpy.logical_or(x1, x2, *args, **kwargs)`Compute the truth value of x1 OR x2 element-wise.\n", + "- `numpy.logical_xor(x1, x2, *args, **kwargs)`Compute the truth value of x1 XOR x2, element-wise.\n", + "\n", + "\n", + "\n", + "\n", + "```python\n", + "【例】计算非x元素的真值。\n", + "\n", + "import numpy as np\n", + "\n", + "print(np.logical_not(3)) \n", + "# False\n", + "print(np.logical_not([True, False, 0, 1]))\n", + "# [False True True False]\n", + "\n", + "x = np.arange(5)\n", + "print(np.logical_not(x < 3))\n", + "# [False False False True True]\n", + "\n", + "【例】计算x1 AND x2元素的真值。\n", + "\n", + "print(np.logical_and(True, False)) \n", + "# False\n", + "print(np.logical_and([True, False], [True, False]))\n", + "# [ True False]\n", + "print(np.logical_and(x > 1, x < 4))\n", + "# [False False True True False]\n", + "\n", + "【例】逐元素计算x1 OR x2的真值。\n", + "\n", + "\n", + "print(np.logical_or(True, False))\n", + "# True\n", + "print(np.logical_or([True, False], [False, False]))\n", + "# [ True False]\n", + "print(np.logical_or(x < 1, x > 3))\n", + "# [ True False False False True]\n", + "\n", + "【例】计算x1 XOR x2的真值,按元素计算。\n", + "\n", + "print(np.logical_xor(True, False))\n", + "# True\n", + "print(np.logical_xor([True, True, False, False], [True, False, True, False]))\n", + "# [False True True False]\n", + "print(np.logical_xor(x < 1, x > 3))\n", + "# [ True False False False True]\n", + "print(np.logical_xor(0, np.eye(2)))\n", + "# [[ True False]\n", + "# [False True]]\n", + "```\n", + "\n", + "\n", + "## 对照\n", + "### numpy.greater\n", + "### numpy.greater_equal\n", + "### numpy.equal\n", + "### numpy.not_equal\n", + "### numpy.less\n", + "### numpy.less_equal\n", + "\n", + "\n", + "- `numpy.greater(x1, x2, *args, **kwargs)` Return the truth value of (x1 > x2) element-wise.\n", + "- `numpy.greater_equal(x1, x2, *args, **kwargs)` Return the truth value of (x1 >= x2) element-wise.\n", + "- `numpy.equal(x1, x2, *args, **kwargs)` Return (x1 == x2) element-wise.\n", + "- `numpy.not_equal(x1, x2, *args, **kwargs)` Return (x1 != x2) element-wise.\n", + "- `numpy.less(x1, x2, *args, **kwargs)` Return the truth value of (x1 < x2) element-wise.\n", + "- `numpy.less_equal(x1, x2, *args, **kwargs)` Return the truth value of (x1 =< x2) element-wise.\n", + "\n", + "\n", + "\n", + "【例】numpy对以上对照函数进行了运算符的重载。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "\n", + "y = x > 2\n", + "print(y)\n", + "print(np.greater(x, 2))\n", + "# [False False True True True True True True]\n", + "\n", + "y = x >= 2\n", + "print(y)\n", + "print(np.greater_equal(x, 2))\n", + "# [False True True True True True True True]\n", + "\n", + "y = x == 2\n", + "print(y)\n", + "print(np.equal(x, 2))\n", + "# [False True False False False False False False]\n", + "\n", + "y = x != 2\n", + "print(y)\n", + "print(np.not_equal(x, 2))\n", + "# [ True False True True True True True True]\n", + "\n", + "y = x < 2\n", + "print(y)\n", + "print(np.less(x, 2))\n", + "# [ True False False False False False False False]\n", + "\n", + "y = x <= 2\n", + "print(y)\n", + "print(np.less_equal(x, 2))\n", + "# [ True True False False False False False False]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = x > 20\n", + "print(y)\n", + "print(np.greater(x, 20))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]]\n", + "\n", + "y = x >= 20\n", + "print(y)\n", + "print(np.greater_equal(x, 20))\n", + "# [[False False False False False]\n", + "# [False False False False True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]]\n", + "\n", + "y = x == 20\n", + "print(y)\n", + "print(np.equal(x, 20))\n", + "# [[False False False False False]\n", + "# [False False False False True]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]]\n", + "\n", + "y = x != 20\n", + "print(y)\n", + "print(np.not_equal(x, 20))\n", + "# [[ True True True True True]\n", + "# [ True True True True False]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]]\n", + "\n", + "\n", + "y = x < 20\n", + "print(y)\n", + "print(np.less(x, 20))\n", + "# [[ True True True True True]\n", + "# [ True True True True False]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]]\n", + "\n", + "y = x <= 20\n", + "print(y)\n", + "print(np.less_equal(x, 20))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200611)\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "y = np.random.randint(10, 40, [5, 5])\n", + "print(y)\n", + "# [[32 28 31 33 37]\n", + "# [23 37 37 30 29]\n", + "# [32 24 10 33 15]\n", + "# [27 17 10 36 16]\n", + "# [25 32 23 39 34]]\n", + "\n", + "z = x > y\n", + "print(z)\n", + "print(np.greater(x, y))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [False False True False True]\n", + "# [False True True False True]\n", + "# [ True False True False True]]\n", + "\n", + "z = x >= y\n", + "print(z)\n", + "print(np.greater_equal(x, y))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [False False True False True]\n", + "# [False True True False True]\n", + "# [ True True True False True]]\n", + "\n", + "z = x == y\n", + "print(z)\n", + "print(np.equal(x, y))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False False False False False]\n", + "# [False True False False False]]\n", + "\n", + "z = x != y\n", + "print(z)\n", + "print(np.not_equal(x, y))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True False True True True]]\n", + "\n", + "z = x < y\n", + "print(z)\n", + "print(np.less(x, y))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True False True False]\n", + "# [ True False False True False]\n", + "# [False False False True False]]\n", + "\n", + "z = x <= y\n", + "print(z)\n", + "print(np.less_equal(x, y))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True False True False]\n", + "# [ True False False True False]\n", + "# [False True False True False]]\n", + "```\n", + "\n", + "【例】注意 numpy 的广播规则。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "\n", + "np.random.seed(20200611)\n", + "y = np.random.randint(10, 50, 5)\n", + "\n", + "print(y)\n", + "# [32 37 30 24 10]\n", + "\n", + "z = x > y\n", + "print(z)\n", + "print(np.greater(x, y))\n", + "# [[False False False False True]\n", + "# [False False False False True]\n", + "# [False False False False True]\n", + "# [False False False True True]\n", + "# [False False True True True]]\n", + "\n", + "z = x >= y\n", + "print(z)\n", + "print(np.greater_equal(x, y))\n", + "# [[False False False False True]\n", + "# [False False False False True]\n", + "# [False False False True True]\n", + "# [False False False True True]\n", + "# [False False True True True]]\n", + "\n", + "z = x == y\n", + "print(z)\n", + "print(np.equal(x, y))\n", + "# [[False False False False False]\n", + "# [False False False False False]\n", + "# [False False False True False]\n", + "# [False False False False False]\n", + "# [False False False False False]]\n", + "\n", + "z = x != y\n", + "print(z)\n", + "print(np.not_equal(x, y))\n", + "# [[ True True True True True]\n", + "# [ True True True True True]\n", + "# [ True True True False True]\n", + "# [ True True True True True]\n", + "# [ True True True True True]]\n", + "\n", + "z = x < y\n", + "print(z)\n", + "print(np.less(x, y))\n", + "# [[ True True True True False]\n", + "# [ True True True True False]\n", + "# [ True True True False False]\n", + "# [ True True True False False]\n", + "# [ True True False False False]]\n", + "\n", + "z = x <= y\n", + "print(z)\n", + "print(np.less_equal(x, y))\n", + "# [[ True True True True False]\n", + "# [ True True True True False]\n", + "# [ True True True True False]\n", + "# [ True True True False False]\n", + "# [ True True False False False]]\n", + "```\n", + "\n", + "### numpy.isclose\n", + "### numpy.allclose\n", + "- `numpy.isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False)` Returns a boolean array where two arrays are element-wise equal within a tolerance.\n", + "- `numpy.allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False)` Returns True if two arrays are element-wise equal within a tolerance. \n", + "\n", + "`numpy.allclose()` 等价于 `numpy.all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan))`。\n", + "\n", + "The tolerance values are positive, typically very small numbers. The relative difference (`rtol * abs(b)`) and the absolute difference `atol` are added together to compare against the absolute difference between `a` and `b`.\n", + "\n", + "判断是否为True的计算依据:\n", + "\n", + "```python\n", + "np.absolute(a - b) <= (atol + rtol * absolute(b))\n", + "\n", + "- atol:float,绝对公差。\n", + "- rtol:float,相对公差。\n", + "```\n", + "\n", + "NaNs are treated as equal if they are in the same place and if `equal_nan=True`. Infs are treated as equal if they are in the same place and of the same sign in both arrays.\n", + "\n", + "【例】比较两个数组是否可以认为相等。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.isclose([1e10, 1e-7], [1.00001e10, 1e-8])\n", + "print(x) # [ True False]\n", + "\n", + "x = np.allclose([1e10, 1e-7], [1.00001e10, 1e-8])\n", + "print(x) # False\n", + "\n", + "x = np.isclose([1e10, 1e-8], [1.00001e10, 1e-9])\n", + "print(x) # [ True True]\n", + "\n", + "x = np.allclose([1e10, 1e-8], [1.00001e10, 1e-9])\n", + "print(x) # True\n", + "\n", + "x = np.isclose([1e10, 1e-8], [1.0001e10, 1e-9])\n", + "print(x) # [False True]\n", + "\n", + "x = np.allclose([1e10, 1e-8], [1.0001e10, 1e-9])\n", + "print(x) # False\n", + "\n", + "x = np.isclose([1.0, np.nan], [1.0, np.nan])\n", + "print(x) # [ True False]\n", + "\n", + "x = np.allclose([1.0, np.nan], [1.0, np.nan])\n", + "print(x) # False\n", + "\n", + "x = np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)\n", + "print(x) # [ True True]\n", + "\n", + "x = np.allclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)\n", + "print(x) # True\n", + "```\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/练习--数学函数,逻辑函数-答案.ipynb b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/练习--数学函数,逻辑函数-答案.ipynb new file mode 100644 index 0000000..d02b03d --- /dev/null +++ b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/练习--数学函数,逻辑函数-答案.ipynb @@ -0,0 +1,715 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 数学函数" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**将数组a中大于30的值替换为30,小于10的值替换为10。**\n", + "\n", + "- `a = np.random.uniform(1, 50, 20)`\n", + "\n", + "【知识点:数学函数、搜索】\n", + "- 如何将大于给定值的所有值替换为给定的截止值?" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:08:51.850958Z", + "start_time": "2020-09-06T03:08:51.759473Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[27.63 14.64 21.8 42.39 1.23 6.96 33.87 41.47 7.7 29.18 44.67 11.25\n", + " 10.08 6.31 11.77 48.95 40.77 9.43 41. 14.43]\n", + "[27.63 14.64 21.8 30. 10. 10. 30. 30. 10. 29.18 30. 11.25\n", + " 10.08 10. 11.77 30. 30. 10. 30. 14.43]\n", + "[27.63 14.64 21.8 30. 10. 10. 30. 30. 10. 29.18 30. 11.25\n", + " 10.08 10. 11.77 30. 30. 10. 30. 14.43]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "np.set_printoptions(precision=2)\n", + "np.random.seed(100)\n", + "a = np.random.uniform(1, 50, 20)\n", + "print(a)\n", + "# [27.63 14.64 21.8 42.39 1.23 6.96 33.87 41.47 7.7 29.18 44.67 11.25\n", + "# 10.08 6.31 11.77 48.95 40.77 9.43 41. 14.43]\n", + "\n", + "# 方法1\n", + "b = np.clip(a, a_min=10, a_max=30)\n", + "print(b)\n", + "# [27.63 14.64 21.8 30. 10. 10. 30. 30. 10. 29.18 30. 11.25\n", + "# 10.08 10. 11.77 30. 30. 10. 30. 14.43]\n", + "\n", + "# 方法2\n", + "b = np.where(a < 10, 10, a)\n", + "b = np.where(b > 30, 30, b)\n", + "print(b)\n", + "# [27.63 14.64 21.8 30. 10. 10. 30. 30. 10. 29.18 30. 11.25\n", + "# 10.08 10. 11.77 30. 30. 10. 30. 14.43]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:21:06.830747Z", + "start_time": "2020-09-06T03:21:06.825756Z" + } + }, + "source": [ + "\n", + "**找到一个一维数字数组a中的所有峰值。峰顶是两边被较小数值包围的点。**\n", + "\n", + "- `a = np.array([1, 3, 7, 1, 2, 6, 0, 1])`\n", + "\n", + "【知识点:数学函数、搜索】\n", + "- 如何在一维数组中找到所有的局部极大值(或峰值)?" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:21:25.424045Z", + "start_time": "2020-09-06T03:21:25.417035Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2 4 -6 1 4 -6 1]\n", + "[ 1 1 -1 1 1 -1 1]\n", + "[ 0 -2 2 0 -2 2]\n", + "[2 5]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.array([1, 3, 7, 1, 2, 6, 0, 1])\n", + "b1 = np.diff(a)\n", + "b2 = np.sign(b1)\n", + "b3 = np.diff(b2)\n", + "\n", + "print(b1) # [ 2 4 -6 1 4 -6 1]\n", + "print(b2) # [ 1 1 -1 1 1 -1 1]\n", + "print(b3) # [ 0 -2 2 0 -2 2]\n", + "index = np.where(np.equal(b3, -2))[0] + 1\n", + "print(index) # [2 5]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**对于给定的一维数组,计算窗口大小为3的移动平均值。**\n", + "\n", + "- `z = np.random.randint(10, size=10)`\n", + "\n", + "【知识点:数学函数】\n", + "- 如何计算numpy数组的移动平均值?" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:23:59.067424Z", + "start_time": "2020-09-06T03:23:59.062437Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[8 8 3 7 7 0 4 2 5 2]\n", + "[6.33 6. 5.67 4.67 3.67 2. 3.67 3. ]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "z = np.random.randint(10, size=10)\n", + "print(z)\n", + "# [8 8 3 7 7 0 4 2 5 2]\n", + "\n", + "def MovingAverage(arr, n=3):\n", + " a = np.cumsum(arr)\n", + " a[n:] = a[n:] - a[:-n]\n", + " return a[n - 1:] / n\n", + "\n", + "\n", + "r = MovingAverage(z, 3)\n", + "print(np.around(r, 2))\n", + "# [6.33 6. 5.67 4.67 3.67 2. 3.67 3. ]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:26:27.187954Z", + "start_time": "2020-09-14T09:26:27.183972Z" + } + }, + "source": [ + "**对一个5x5的随机矩阵做归一化**\n", + "\n", + "【知识点:数学函数】\n", + "- (提示: (x - min) / (max - min))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:26:59.520324Z", + "start_time": "2020-09-14T09:26:59.515666Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0.65852707 0.23160203 0.9700425 0.43393441 0.36950354]\n", + " [0.58585632 0.01877358 0. 0.27782335 0.89654906]\n", + " [0.71307774 0.32030221 0.55187887 0.01411576 0.38903753]\n", + " [0.05702349 0.40824762 0.23277188 0.74335934 0.72125366]\n", + " [0.59816442 0.98727663 1. 0.86466287 0.42760849]]\n" + ] + } + ], + "source": [ + "Z = np.random.random((5,5))\n", + "Zmax, Zmin = Z.max(), Z.min()\n", + "Z = (Z - Zmin)/(Zmax - Zmin)\n", + "print(Z)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**用五种不同的方法去提取一个随机数组的整数部分**\n", + "\n", + "【知识点:数学函数】\n", + "\n", + "- (提示: %, np.floor, np.ceil, astype, np.trunc)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:31:37.950320Z", + "start_time": "2020-09-14T09:31:37.944304Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[8. 5. 5. 1. 2. 7. 0. 1. 5. 9.]\n", + "[8. 5. 5. 1. 2. 7. 0. 1. 5. 9.]\n", + "[8. 5. 5. 1. 2. 7. 0. 1. 5. 9.]\n", + "[8 5 5 1 2 7 0 1 5 9]\n", + "[8. 5. 5. 1. 2. 7. 0. 1. 5. 9.]\n" + ] + } + ], + "source": [ + "Z = np.random.uniform(0,10,10)\n", + "\n", + "print (Z - Z%1)\n", + "print (np.floor(Z))\n", + "print (np.ceil(Z)-1)\n", + "print (Z.astype(int))\n", + "print (np.trunc(Z))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**考虑一维数组Z,构建一个二维数组,其第一行为(Z [0],Z [1],Z [2]),随后的每一行都移位1(最后一行应为(Z [ -3],Z [-2],Z [-1])**\n", + "\n", + "【知识点:数学函数】\n", + "\n", + "- (提示np.lib.stride_tricks)" + ] + }, + { + "attachments": { + "image.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]--------> ![image.png](attachment:image.png) " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T13:38:56.805424Z", + "start_time": "2020-09-14T13:38:56.800436Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.arange(10).itemsize" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T13:32:50.080815Z", + "start_time": "2020-09-14T13:32:49.737937Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0 1 2]\n", + " [1 2 3]\n", + " [2 3 4]\n", + " [3 4 5]\n", + " [4 5 6]\n", + " [5 6 7]\n", + " [6 7 8]\n", + " [7 8 9]]\n" + ] + } + ], + "source": [ + "from numpy.lib import stride_tricks\n", + "def rolling(a, window):\n", + " shape = (a.size - window + 1, window)\n", + " strides = (a.itemsize, a.itemsize)\n", + " return stride_tricks.as_strided(a, shape=shape, strides=strides)\n", + "Z = rolling(np.arange(10), 3)\n", + "print (Z)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**考虑两组点集P0和P1去描述一组线(二维)和一个点p,如何计算点p到每一条线 i (P0[i],P1[i])的距离?**\n", + "\n", + "【知识点:数学函数】\n", + "- 提示 设P(x0,y0),直线方程为:Ax+By+C=0\n", + "则P到直线的距离为:d=|Ax0+By0+C|/√(A²+B²)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T05:37:30.811695Z", + "start_time": "2020-09-15T05:37:30.805709Z" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "def distance(P0,P1,p):\n", + " A=-1/(P1[:,0]-P0[:,0])\n", + " B=1/(P1[:,1]-P0[:,1])\n", + " C=P0[:,0]/(P1[:,0]-P0[:,0])-P0[:,1]/(P1[:,1]-P0[:,1])\n", + " return np.abs(A*p[:,0]+B*p[:,1]+C)/np.sqrt(A**2+B**2)" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T05:37:37.692332Z", + "start_time": "2020-09-15T05:37:37.687379Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 2.41120585 7.05924485 5.94906338 3.89096895 7.68364539 14.01851392\n", + " 4.28148124 2.29582076 6.19155339 15.55087594]\n" + ] + } + ], + "source": [ + "P0 = np.random.uniform(-10,10,(10,2))\n", + "P1 = np.random.uniform(-10,10,(10,2))\n", + "p = np.random.uniform(-10,10,( 1,2))\n", + "\n", + "print (distance(P0, P1, p))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:33:06.525406Z", + "start_time": "2020-09-06T02:33:06.520453Z" + } + }, + "source": [ + "## 逻辑函数" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**获取a和b元素匹配的位置。**\n", + "- `a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])`\n", + "- `b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])`\n", + "\n", + "【知识点:逻辑函数】\n", + "- 如何得到两个数组元素匹配的位置?" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:53:59.537622Z", + "start_time": "2020-09-06T02:53:59.531638Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(array([1, 3, 5, 7], dtype=int64),)\n", + "(array([1, 3, 5, 7], dtype=int64),)\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])\n", + "b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])\n", + "mask = np.equal(a, b)\n", + "\n", + "# 方法1\n", + "x = np.where(mask)\n", + "print(x) # (array([1, 3, 5, 7], dtype=int64),)\n", + "\n", + "# 方法2\n", + "x = np.nonzero(mask)\n", + "print(x) # (array([1, 3, 5, 7], dtype=int64),)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:54:19.320517Z", + "start_time": "2020-09-06T02:54:19.315496Z" + } + }, + "source": [ + "**获取5到10 之间的所有元素。**\n", + "- `a = np.array([2, 6, 1, 9, 10, 3, 27])`\n", + "\n", + "【知识点:逻辑函数】\n", + "- 如何从numpy数组中提取给定范围内的所有元素?" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:55:11.162117Z", + "start_time": "2020-09-06T02:55:11.156161Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 6 9 10]\n", + "[ 6 9 10]\n", + "[ 6 9 10]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.array([2, 6, 1, 9, 10, 3, 27])\n", + "mask = np.logical_and(np.greater_equal(a, 5), np.less_equal(a, 10))\n", + "\n", + "# 方法1\n", + "x = np.where(mask)\n", + "print(a[x]) # [ 6 9 10]\n", + "\n", + "# 方法2\n", + "x = np.nonzero(mask)\n", + "print(a[x]) # [ 6 9 10]\n", + "\n", + "# 方法3\n", + "x = a[np.logical_and(a >= 5, a <= 10)]\n", + "print(x) # [ 6 9 10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**对于两个随机数组A和B,检查他们是否相等**\n", + "\n", + "【知识点:逻辑函数】\n", + "\n", + "- (提示: np.allclose, np.array_equal)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:35:57.408576Z", + "start_time": "2020-09-14T09:35:57.404623Z" + } + }, + "outputs": [], + "source": [ + "A = np.random.randint(0,2,5)\n", + "B = np.random.randint(0,2,5)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:35:58.285123Z", + "start_time": "2020-09-14T09:35:58.280479Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n" + ] + } + ], + "source": [ + "\n", + "# Assuming identical shape of the arrays and a tolerance for the comparison of values\n", + "equal = np.allclose(A,B)\n", + "print(equal)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**何对布尔值取反,或者原位(in-place)改变浮点数的符号(sign)?**\n", + "\n", + "【知识点:逻辑函数】\n", + "- (提示: np.logical_not, np.negative)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T14:05:59.290471Z", + "start_time": "2020-09-14T14:05:59.284521Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1]\n" + ] + }, + { + "data": { + "text/plain": [ + "array([1, 0])" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Z = np.array([0,1])\n", + "print(Z)\n", + "np.logical_not(Z, out=Z)\n", + "# Z = np.random.uniform(-1.0,1.0,100)\n", + "\n", + "# np.negative(Z, out=Z)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T14:08:05.101330Z", + "start_time": "2020-09-14T14:08:05.096343Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0.2 1.15]\n" + ] + }, + { + "data": { + "text/plain": [ + "array([-0.2 , -1.15])" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Z = np.array([0.2,1.15])\n", + "print(Z)\n", + "np.negative(Z, out=Z)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "224.2px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/练习--数学函数,逻辑函数.ipynb b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/练习--数学函数,逻辑函数.ipynb new file mode 100644 index 0000000..885672e --- /dev/null +++ b/IntroductionToNumpy/numpy/task04-2天-数学函数及逻辑函数/练习--数学函数,逻辑函数.ipynb @@ -0,0 +1,227 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 数学函数" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **将数组a中大于30的值替换为30,小于10的值替换为10。**\n", + "\n", + "- `a = np.random.uniform(1, 50, 20)`\n", + "\n", + "【知识点:数学函数、搜索】\n", + "- 如何将大于给定值的所有值替换为给定的截止值?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **找到一个一维数字数组a中的所有峰值。峰顶是两边被较小数值包围的点。**\n", + "\n", + "- `a = np.array([1, 3, 7, 1, 2, 6, 0, 1])`\n", + "\n", + "【知识点:数学函数、搜索】\n", + "- 如何在一维数组中找到所有的局部极大值(或峰值)?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **对于给定的一维数组,计算窗口大小为3的移动平均值。**\n", + "\n", + "- `z = np.random.randint(10, size=10)`\n", + "\n", + "【知识点:数学函数】\n", + "- 如何计算numpy数组的移动平均值?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **对一个5x5的随机矩阵做归一化**\n", + "\n", + "-`Z = np.random.random((5,5))` \n", + "\n", + "【知识点:数学函数】\n", + "- (提示: (x - min) / (max - min))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **用五种不同的方法去提取一个随机数组的整数部分**\n", + "\n", + "- `Z = np.random.uniform(0,10,10) `\n", + "\n", + "【知识点:数学函数】\n", + "\n", + "- (提示: %, np.floor, np.ceil, astype, np.trunc)" + ] + }, + { + "attachments": { + "image.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **考虑一维数组Z,构建一个二维数组,其第一行为(Z [0],Z [1],Z [2]),随后的每一行都移位1(最后一行应为(Z [ -3],Z [-2],Z [-1])**\n", + "\n", + "【知识点:数学函数】\n", + "\n", + "- (提示np.lib.stride_tricks)\n", + "\n", + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]--------> ![image.png](attachment:image.png) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **考虑两组点集P0和P1去描述一组线(二维)和一个点p,如何计算点p到每一条线 i (P0[i],P1[i])的距离?**\n", + "- `P0 = np.random.uniform(-10,10,(10,2))\n", + "P1 = np.random.uniform(-10,10,(10,2))\n", + "p = np.random.uniform(-10,10,( 1,2))`\n", + "\n", + "【知识点:数学函数】\n", + "- 提示 设P(x0,y0),直线方程为:Ax+By+C=0\n", + "则P到直线的距离为:d=|Ax0+By0+C|/√(A²+B²)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 逻辑函数" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **获取a和b元素匹配的位置。**\n", + "- `a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])`\n", + "- `b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])`\n", + "\n", + "【知识点:逻辑函数】\n", + "- 如何得到两个数组元素匹配的位置?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **获取5到10 之间的所有元素。**\n", + "- `a = np.array([2, 6, 1, 9, 10, 3, 27])`\n", + "\n", + "【知识点:逻辑函数】\n", + "- 如何从numpy数组中提取给定范围内的所有元素?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **对于两个随机数组A和B,检查他们是否相等**\n", + "- `A = np.random.randint(0,2,5)\n", + "B = np.random.randint(0,2,5)`\n", + "\n", + "【知识点:逻辑函数】\n", + "\n", + "- (提示: np.allclose, np.array_equal)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **何对布尔值取反,或者原位(in-place)改变浮点数的符号(sign)?**\n", + "\n", + "【知识点:逻辑函数】\n", + "- (提示: np.logical_not, np.negative)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/.ipynb_checkpoints/练习-排序搜索计数,集合操作-checkpoint.ipynb b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/.ipynb_checkpoints/练习-排序搜索计数,集合操作-checkpoint.ipynb new file mode 100644 index 0000000..7cbf4af --- /dev/null +++ b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/.ipynb_checkpoints/练习-排序搜索计数,集合操作-checkpoint.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 排序搜索计数" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **如何通过第n列对一个数组进行排序**\n", + "- `Z = np.random.randint(0,10,(3,3))`\n", + "\n", + "【知识点:排序】\n", + "\n", + "- (提示: argsort)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **从`arr`中提取所有奇数。**\n", + "\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何从一维数组中提取满足指定条件的元素?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **将`arr`中的偶数元素替换为0。**\n", + "\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何用numpy数组中的另一个值替换满足条件的元素项?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ** 将 `arr` 中的所有偶数元素替换为0,而不改变arr。**\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何在不影响原始数组的情况下替换满足条件的元素项?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **获取给定数组a中前5个最大值的位置。**\n", + "\n", + "- `a = np.random.uniform(1, 50, 20)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何从numpy数组中获取最大的n个值的位置?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **删除一维numpy数组中所有NaN值。**\n", + "\n", + "- `a = np.array([1, 2, 3, np.nan, 5, 6, 7, np.nan])`\n", + "\n", + "【知识点:逻辑函数、搜索】\n", + "- 如何删除numpy数组中的缺失值?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 集合操作" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/.ipynb_checkpoints/练习-排序搜索计数,集合操作-答案-checkpoint.ipynb b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/.ipynb_checkpoints/练习-排序搜索计数,集合操作-答案-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/.ipynb_checkpoints/练习-排序搜索计数,集合操作-答案-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/09. 排序,搜索和计数.ipynb b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/09. 排序,搜索和计数.ipynb new file mode 100644 index 0000000..03c5587 --- /dev/null +++ b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/09. 排序,搜索和计数.ipynb @@ -0,0 +1,828 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 排序,搜索和计数\n", + "## 排序\n", + "\n", + "- `numpy.sort(a[, axis=-1, kind='quicksort', order=None])` Return a sorted **copy** of an array.\n", + " - axis:排序沿数组的(轴)方向,0表示按行,1表示按列,None表示展开来排序,默认为-1,表示沿最后的轴排序。\n", + " - kind:排序的算法,提供了快排'quicksort'、混排'mergesort'、堆排'heapsort', 默认为‘quicksort'。\n", + " - order:排序的字段名,可指定字段排序,默认为None。\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200612)\n", + "x = np.random.rand(5, 5) * 10\n", + "x = np.around(x, 2)\n", + "print(x)\n", + "# [[2.32 7.54 9.78 1.73 6.22]\n", + "# [6.93 5.17 9.28 9.76 8.25]\n", + "# [0.01 4.23 0.19 1.73 9.27]\n", + "# [7.99 4.97 0.88 7.32 4.29]\n", + "# [9.05 0.07 8.95 7.9 6.99]]\n", + "\n", + "y = np.sort(x)\n", + "print(y)\n", + "# [[1.73 2.32 6.22 7.54 9.78]\n", + "# [5.17 6.93 8.25 9.28 9.76]\n", + "# [0.01 0.19 1.73 4.23 9.27]\n", + "# [0.88 4.29 4.97 7.32 7.99]\n", + "# [0.07 6.99 7.9 8.95 9.05]]\n", + "\n", + "y = np.sort(x, axis=0)\n", + "print(y)\n", + "# [[0.01 0.07 0.19 1.73 4.29]\n", + "# [2.32 4.23 0.88 1.73 6.22]\n", + "# [6.93 4.97 8.95 7.32 6.99]\n", + "# [7.99 5.17 9.28 7.9 8.25]\n", + "# [9.05 7.54 9.78 9.76 9.27]]\n", + "\n", + "y = np.sort(x, axis=1)\n", + "print(y)\n", + "# [[1.73 2.32 6.22 7.54 9.78]\n", + "# [5.17 6.93 8.25 9.28 9.76]\n", + "# [0.01 0.19 1.73 4.23 9.27]\n", + "# [0.88 4.29 4.97 7.32 7.99]\n", + "# [0.07 6.99 7.9 8.95 9.05]]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "dt = np.dtype([('name', 'S10'), ('age', np.int)])\n", + "a = np.array([(\"Mike\", 21), (\"Nancy\", 25), (\"Bob\", 17), (\"Jane\", 27)], dtype=dt)\n", + "b = np.sort(a, order='name')\n", + "print(b)\n", + "# [(b'Bob', 17) (b'Jane', 27) (b'Mike', 21) (b'Nancy', 25)]\n", + "\n", + "b = np.sort(a, order='age')\n", + "print(b)\n", + "# [(b'Bob', 17) (b'Mike', 21) (b'Nancy', 25) (b'Jane', 27)]\n", + "```\n", + "\n", + "\n", + "如果排序后,想用元素的索引位置替代排序后的实际结果,该怎么办呢?\n", + "\n", + "- `numpy.argsort(a[, axis=-1, kind='quicksort', order=None])` Returns the indices that would sort an array.\n", + "\n", + "\n", + "\n", + "【例】对数组沿给定轴执行间接排序,并使用指定排序类型返回数据的索引数组。这个索引数组用于构造排序后的数组。\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200612)\n", + "x = np.random.randint(0, 10, 10)\n", + "print(x)\n", + "# [6 1 8 5 5 4 1 2 9 1]\n", + "\n", + "y = np.argsort(x)\n", + "print(y)\n", + "# [1 6 9 7 5 3 4 0 2 8]\n", + "\n", + "print(x[y])\n", + "# [1 1 1 2 4 5 5 6 8 9]\n", + "\n", + "y = np.argsort(-x)\n", + "print(y)\n", + "# [8 2 0 3 4 5 7 1 6 9]\n", + "\n", + "print(x[y])\n", + "# [9 8 6 5 5 4 2 1 1 1]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200612)\n", + "x = np.random.rand(5, 5) * 10\n", + "x = np.around(x, 2)\n", + "print(x)\n", + "# [[2.32 7.54 9.78 1.73 6.22]\n", + "# [6.93 5.17 9.28 9.76 8.25]\n", + "# [0.01 4.23 0.19 1.73 9.27]\n", + "# [7.99 4.97 0.88 7.32 4.29]\n", + "# [9.05 0.07 8.95 7.9 6.99]]\n", + "\n", + "y = np.argsort(x)\n", + "print(y)\n", + "# [[3 0 4 1 2]\n", + "# [1 0 4 2 3]\n", + "# [0 2 3 1 4]\n", + "# [2 4 1 3 0]\n", + "# [1 4 3 2 0]]\n", + "\n", + "y = np.argsort(x, axis=0)\n", + "print(y)\n", + "# [[2 4 2 0 3]\n", + "# [0 2 3 2 0]\n", + "# [1 3 4 3 4]\n", + "# [3 1 1 4 1]\n", + "# [4 0 0 1 2]]\n", + "\n", + "y = np.argsort(x, axis=1)\n", + "print(y)\n", + "# [[3 0 4 1 2]\n", + "# [1 0 4 2 3]\n", + "# [0 2 3 1 4]\n", + "# [2 4 1 3 0]\n", + "# [1 4 3 2 0]]\n", + "\n", + "y = np.array([np.take(x[i], np.argsort(x[i])) for i in range(5)]) \n", + "#numpy.take(a, indices, axis=None, out=None, mode='raise')沿轴从数组中获取元素。\n", + "print(y)\n", + "# [[1.73 2.32 6.22 7.54 9.78]\n", + "# [5.17 6.93 8.25 9.28 9.76]\n", + "# [0.01 0.19 1.73 4.23 9.27]\n", + "# [0.88 4.29 4.97 7.32 7.99]\n", + "# [0.07 6.99 7.9 8.95 9.05]]\n", + "```\n", + "\n", + "如何将数据按照某一指标进行排序呢?\n", + "\n", + "- `numpy.lexsort(keys[, axis=-1])` Perform an indirect stable sort using a sequence of keys.(使用键序列执行间接稳定排序。)\n", + "\n", + "- 给定多个可以在电子表格中解释为列的排序键,lexsort返回一个整数索引数组,该数组描述了按多个列排序的顺序。序列中的最后一个键用于主排序顺序,倒数第二个键用于辅助排序顺序,依此类推。keys参数必须是可以转换为相同形状的数组的对象序列。如果为keys参数提供了2D数组,则将其行解释为排序键,并根据最后一行,倒数第二行等进行排序。\n", + "\n", + "\n", + "\n", + "【例】按照第一列的升序或者降序对整体数据进行排序。\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200612)\n", + "x = np.random.rand(5, 5) * 10\n", + "x = np.around(x, 2)\n", + "print(x)\n", + "# [[2.32 7.54 9.78 1.73 6.22]\n", + "# [6.93 5.17 9.28 9.76 8.25]\n", + "# [0.01 4.23 0.19 1.73 9.27]\n", + "# [7.99 4.97 0.88 7.32 4.29]\n", + "# [9.05 0.07 8.95 7.9 6.99]]\n", + "\n", + "index = np.lexsort([x[:, 0]])\n", + "print(index)\n", + "# [2 0 1 3 4]\n", + "\n", + "y = x[index]\n", + "print(y)\n", + "# [[0.01 4.23 0.19 1.73 9.27]\n", + "# [2.32 7.54 9.78 1.73 6.22]\n", + "# [6.93 5.17 9.28 9.76 8.25]\n", + "# [7.99 4.97 0.88 7.32 4.29]\n", + "# [9.05 0.07 8.95 7.9 6.99]]\n", + "\n", + "index = np.lexsort([-1 * x[:, 0]])\n", + "print(index)\n", + "# [4 3 1 0 2]\n", + "\n", + "y = x[index]\n", + "print(y)\n", + "# [[9.05 0.07 8.95 7.9 6.99]\n", + "# [7.99 4.97 0.88 7.32 4.29]\n", + "# [6.93 5.17 9.28 9.76 8.25]\n", + "# [2.32 7.54 9.78 1.73 6.22]\n", + "# [0.01 4.23 0.19 1.73 9.27]]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 5, 1, 4, 3, 4, 4])\n", + "y = np.array([9, 4, 0, 4, 0, 2, 1])\n", + "a = np.lexsort([x])\n", + "b = np.lexsort([y])\n", + "print(a)\n", + "# [0 2 4 3 5 6 1]\n", + "print(x[a])\n", + "# [1 1 3 4 4 4 5]\n", + "\n", + "print(b)\n", + "# [2 4 6 5 1 3 0]\n", + "print(y[b])\n", + "# [0 0 1 2 4 4 9]\n", + "\n", + "z = np.lexsort([y, x])\n", + "print(z)\n", + "# [2 0 4 6 5 3 1]\n", + "print(x[z])\n", + "# [1 1 3 4 4 4 5]\n", + "\n", + "z = np.lexsort([x, y])\n", + "print(z)\n", + "# [2 4 6 5 3 1 0]\n", + "print(y[z])\n", + "# [0 0 1 2 4 4 9]\n", + "```\n", + "\n", + "- `numpy.partition(a, kth, axis=-1, kind='introselect', order=None)` Return a partitioned copy of an array.\n", + "\n", + "Creates a copy of the array with its elements rearranged in such a way that the value of the element in k-th position is in the position it would be in a sorted array. All elements smaller than the k-th element are moved before this element and all equal or greater are moved behind it. The ordering of the elements in the two partitions is undefined.\n", + "\n", + "\n", + "【例】以索引是 kth 的元素为基准,将元素分成两部分,即大于该元素的放在其后面,小于该元素的放在其前面,这里有点类似于快排。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "x = np.random.randint(1, 30, [8, 3])\n", + "print(x)\n", + "# [[ 9 25 4]\n", + "# [ 8 24 16]\n", + "# [17 11 21]\n", + "# [ 3 22 3]\n", + "# [ 3 15 3]\n", + "# [18 17 25]\n", + "# [16 5 12]\n", + "# [29 27 17]]\n", + "\n", + "y = np.sort(x, axis=0)\n", + "print(y)\n", + "# [[ 3 5 3]\n", + "# [ 3 11 3]\n", + "# [ 8 15 4]\n", + "# [ 9 17 12]\n", + "# [16 22 16]\n", + "# [17 24 17]\n", + "# [18 25 21]\n", + "# [29 27 25]]\n", + "\n", + "z = np.partition(x, kth=2, axis=0)\n", + "print(z)\n", + "# [[ 3 5 3]\n", + "# [ 3 11 3]\n", + "# [ 8 15 4]\n", + "# [ 9 22 21]\n", + "# [17 24 16]\n", + "# [18 17 25]\n", + "# [16 25 12]\n", + "# [29 27 17]]\n", + "```\n", + "【例】选取每一列第三小的数\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "x = np.random.randint(1, 30, [8, 3])\n", + "print(x)\n", + "# [[ 9 25 4]\n", + "# [ 8 24 16]\n", + "# [17 11 21]\n", + "# [ 3 22 3]\n", + "# [ 3 15 3]\n", + "# [18 17 25]\n", + "# [16 5 12]\n", + "# [29 27 17]]\n", + "z = np.partition(x, kth=2, axis=0)\n", + "print(z[2])\n", + "# [ 8 15 4]\n", + "```\n", + "\n", + "【例】选取每一列第三大的数据\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "x = np.random.randint(1, 30, [8, 3])\n", + "print(x)\n", + "# [[ 9 25 4]\n", + "# [ 8 24 16]\n", + "# [17 11 21]\n", + "# [ 3 22 3]\n", + "# [ 3 15 3]\n", + "# [18 17 25]\n", + "# [16 5 12]\n", + "# [29 27 17]]\n", + "z = np.partition(x, kth=-3, axis=0)\n", + "print(z[-3])\n", + "# [17 24 17]\n", + "```\n", + "\n", + "\n", + "- `numpy.argpartition(a, kth, axis=-1, kind='introselect', order=None)`\n", + "\n", + "Perform an indirect partition along the given axis using the algorithm specified by the `kind` keyword. It returns an array of indices of the same shape as `a` that index data along the given axis in partitioned order.\n", + "\n", + "【例】\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "x = np.random.randint(1, 30, [8, 3])\n", + "print(x)\n", + "# [[ 9 25 4]\n", + "# [ 8 24 16]\n", + "# [17 11 21]\n", + "# [ 3 22 3]\n", + "# [ 3 15 3]\n", + "# [18 17 25]\n", + "# [16 5 12]\n", + "# [29 27 17]]\n", + "\n", + "y = np.argsort(x, axis=0)\n", + "print(y)\n", + "# [[3 6 3]\n", + "# [4 2 4]\n", + "# [1 4 0]\n", + "# [0 5 6]\n", + "# [6 3 1]\n", + "# [2 1 7]\n", + "# [5 0 2]\n", + "# [7 7 5]]\n", + "\n", + "z = np.argpartition(x, kth=2, axis=0)\n", + "print(z)\n", + "# [[3 6 3]\n", + "# [4 2 4]\n", + "# [1 4 0]\n", + "# [0 3 2]\n", + "# [2 1 1]\n", + "# [5 5 5]\n", + "# [6 0 6]\n", + "# [7 7 7]]\n", + "```\n", + "\n", + "【例】选取每一列第三小的数的索引\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "x = np.random.randint(1, 30, [8, 3])\n", + "print(x)\n", + "# [[ 9 25 4]\n", + "# [ 8 24 16]\n", + "# [17 11 21]\n", + "# [ 3 22 3]\n", + "# [ 3 15 3]\n", + "# [18 17 25]\n", + "# [16 5 12]\n", + "# [29 27 17]]\n", + "\n", + "z = np.argpartition(x, kth=2, axis=0)\n", + "print(z[2])\n", + "# [1 4 0]\n", + "```\n", + "\n", + "【例】选取每一列第三大的数的索引\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "x = np.random.randint(1, 30, [8, 3])\n", + "print(x)\n", + "# [[ 9 25 4]\n", + "# [ 8 24 16]\n", + "# [17 11 21]\n", + "# [ 3 22 3]\n", + "# [ 3 15 3]\n", + "# [18 17 25]\n", + "# [16 5 12]\n", + "# [29 27 17]]\n", + "\n", + "z = np.argpartition(x, kth=-3, axis=0)\n", + "print(z[-3])\n", + "# [2 1 7]\n", + "```\n", + "\n", + "\n", + "---\n", + "## 搜索\n", + "\n", + "- `numpy.argmax(a[, axis=None, out=None])`Returns the indices of the maximum values along an axis.\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200612)\n", + "x = np.random.rand(5, 5) * 10\n", + "x = np.around(x, 2)\n", + "print(x)\n", + "# [[2.32 7.54 9.78 1.73 6.22]\n", + "# [6.93 5.17 9.28 9.76 8.25]\n", + "# [0.01 4.23 0.19 1.73 9.27]\n", + "# [7.99 4.97 0.88 7.32 4.29]\n", + "# [9.05 0.07 8.95 7.9 6.99]]\n", + "\n", + "y = np.argmax(x)\n", + "print(y) # 2\n", + "\n", + "y = np.argmax(x, axis=0)\n", + "print(y)\n", + "# [4 0 0 1 2]\n", + "\n", + "y = np.argmax(x, axis=1)\n", + "print(y)\n", + "# [2 3 4 0 0]\n", + "```\n", + "\n", + "- `numpy.argmin(a[, axis=None, out=None])`Returns the indices of the minimum values along an axis.\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200612)\n", + "x = np.random.rand(5, 5) * 10\n", + "x = np.around(x, 2)\n", + "print(x)\n", + "# [[2.32 7.54 9.78 1.73 6.22]\n", + "# [6.93 5.17 9.28 9.76 8.25]\n", + "# [0.01 4.23 0.19 1.73 9.27]\n", + "# [7.99 4.97 0.88 7.32 4.29]\n", + "# [9.05 0.07 8.95 7.9 6.99]]\n", + "\n", + "y = np.argmin(x)\n", + "print(y) # 10\n", + "\n", + "y = np.argmin(x, axis=0)\n", + "print(y)\n", + "# [2 4 2 0 3]\n", + "\n", + "y = np.argmin(x, axis=1)\n", + "print(y)\n", + "# [3 1 0 2 1]\n", + "```\n", + "\n", + "\n", + "- `numppy.nonzero(a)` Return the indices of the elements that are non-zero.\n", + "\n", + ",其值为非零元素的下标在对应轴上的值。\n", + "\n", + "1. 只有`a`中非零元素才会有索引值,那些零值元素没有索引值。\n", + "2. 返回一个长度为`a.ndim`的元组(tuple),元组的每个元素都是一个整数数组(array)。\n", + "3. 每一个array均是从一个维度上来描述其索引值。比如,如果`a`是一个二维数组,则tuple包含两个array,第一个array从行维度来描述索引值;第二个array从列维度来描述索引值。\n", + "4. 该 `np.transpose(np.nonzero(x))` 函数能够描述出每一个非零元素在不同维度的索引值。\n", + "5. 通过`a[nonzero(a)]`得到所有`a`中的非零值。\n", + "\n", + "【例】一维数组\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([0, 2, 3])\n", + "print(x) # [0 2 3]\n", + "print(x.shape) # (3,)\n", + "print(x.ndim) # 1\n", + "\n", + "y = np.nonzero(x)\n", + "print(y) # (array([1, 2], dtype=int64),)\n", + "print(np.array(y)) # [[1 2]]\n", + "print(np.array(y).shape) # (1, 2)\n", + "print(np.array(y).ndim) # 2\n", + "print(np.transpose(y))\n", + "# [[1]\n", + "# [2]]\n", + "print(x[np.nonzero(x)])\n", + "#[2, 3]\n", + "```\n", + "\n", + "【例】二维数组\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[3, 0, 0], [0, 4, 0], [5, 6, 0]])\n", + "print(x)\n", + "# [[3 0 0]\n", + "# [0 4 0]\n", + "# [5 6 0]]\n", + "print(x.shape) # (3, 3)\n", + "print(x.ndim) # 2\n", + "\n", + "y = np.nonzero(x)\n", + "print(y)\n", + "# (array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64))\n", + "print(np.array(y))\n", + "# [[0 1 2 2]\n", + "# [0 1 0 1]]\n", + "print(np.array(y).shape) # (2, 4)\n", + "print(np.array(y).ndim) # 2\n", + "\n", + "y = x[np.nonzero(x)]\n", + "print(y) # [3 4 5 6]\n", + "\n", + "y = np.transpose(np.nonzero(x))\n", + "print(y)\n", + "# [[0 0]\n", + "# [1 1]\n", + "# [2 0]\n", + "# [2 1]]\n", + "```\n", + "【例】三维数组\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[[0, 1], [1, 0]], [[0, 1], [1, 0]], [[0, 0], [1, 0]]])\n", + "print(x)\n", + "# [[[0 1]\n", + "# [1 0]]\n", + "#\n", + "# [[0 1]\n", + "# [1 0]]\n", + "#\n", + "# [[0 0]\n", + "# [1 0]]]\n", + "print(np.shape(x)) # (3, 2, 2)\n", + "print(x.ndim) # 3\n", + "\n", + "y = np.nonzero(x)\n", + "print(np.array(y))\n", + "# [[0 0 1 1 2]\n", + "# [0 1 0 1 1]\n", + "# [1 0 1 0 0]]\n", + "print(np.array(y).shape) # (3, 5)\n", + "print(np.array(y).ndim) # 2\n", + "print(y)\n", + "# (array([0, 0, 1, 1, 2], dtype=int64), array([0, 1, 0, 1, 1], dtype=int64), array([1, 0, 1, 0, 0], dtype=int64))\n", + "print(x[np.nonzero(x)])\n", + "#[1 1 1 1 1]\n", + "```\n", + "\n", + "【例】`nonzero()`将布尔数组转换成整数数组进行操作。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n", + "print(x)\n", + "# [[1 2 3]\n", + "# [4 5 6]\n", + "# [7 8 9]]\n", + "\n", + "y = x > 3\n", + "print(y)\n", + "# [[False False False]\n", + "# [ True True True]\n", + "# [ True True True]]\n", + "\n", + "y = np.nonzero(x > 3)\n", + "print(y)\n", + "# (array([1, 1, 1, 2, 2, 2], dtype=int64), array([0, 1, 2, 0, 1, 2], dtype=int64))\n", + "\n", + "y = x[np.nonzero(x > 3)]\n", + "print(y)\n", + "# [4 5 6 7 8 9]\n", + "\n", + "y = x[x > 3]\n", + "print(y)\n", + "# [4 5 6 7 8 9]\n", + "```\n", + "\n", + "- `numpy.where(condition, [x=None, y=None])` Return elements chosen from `x` or `y` depending on `condition`.\n", + "\n", + "【例】满足条件`condition`,输出`x`,不满足输出`y`。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.arange(10)\n", + "print(x)\n", + "# [0 1 2 3 4 5 6 7 8 9]\n", + "\n", + "y = np.where(x < 5, x, 10 * x)\n", + "print(y)\n", + "# [ 0 1 2 3 4 50 60 70 80 90]\n", + "\n", + "x = np.array([[0, 1, 2],\n", + " [0, 2, 4],\n", + " [0, 3, 6]])\n", + "y = np.where(x < 4, x, -1)\n", + "print(y)\n", + "# [[ 0 1 2]\n", + "# [ 0 2 -1]\n", + "# [ 0 3 -1]]\n", + "```\n", + "\n", + "【例】只有`condition`,没有`x`和`y`,则输出满足条件 (即非0) 元素的坐标 (等价于`numpy.nonzero`)。这里的坐标以tuple的形式给出,通常原数组有多少维,输出的tuple中就包含几个数组,分别对应符合条件元素的各维坐标。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n", + "y = np.where(x > 5)\n", + "print(y)\n", + "# (array([5, 6, 7], dtype=int64),)\n", + "print(x[y])\n", + "# [6 7 8]\n", + "\n", + "y = np.nonzero(x > 5)\n", + "print(y)\n", + "# (array([5, 6, 7], dtype=int64),)\n", + "print(x[y])\n", + "# [6 7 8]\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.where(x > 25)\n", + "print(y)\n", + "# (array([3, 3, 3, 3, 3, 4, 4, 4, 4, 4], dtype=int64), array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4], dtype=int64))\n", + "\n", + "print(x[y])\n", + "# [26 27 28 29 30 31 32 33 34 35]\n", + "\n", + "y = np.nonzero(x > 25)\n", + "print(y)\n", + "# (array([3, 3, 3, 3, 3, 4, 4, 4, 4, 4], dtype=int64), array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4], dtype=int64))\n", + "print(x[y])\n", + "# [26 27 28 29 30 31 32 33 34 35]\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "- `numpy.searchsorted(a, v[, side='left', sorter=None])` Find indices where elements should be inserted to maintain order.\n", + " - a:一维输入数组。当`sorter`参数为`None`的时候,`a`必须为升序数组;否则,`sorter`不能为空,存放`a`中元素的`index`,用于反映`a`数组的升序排列方式。\n", + " - v:插入`a`数组的值,可以为单个元素,`list`或者`ndarray`。\n", + " - side:查询方向,当为`left`时,将返回第一个符合条件的元素下标;当为`right`时,将返回最后一个符合条件的元素下标。\n", + " - sorter:一维数组存放`a`数组元素的 index,index 对应元素为升序。\n", + "\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([0, 1, 5, 9, 11, 18, 26, 33])\n", + "y = np.searchsorted(x, 15)\n", + "print(y) # 5\n", + "\n", + "y = np.searchsorted(x, 15, side='right')\n", + "print(y) # 5\n", + "\n", + "y = np.searchsorted(x, -1)\n", + "print(y) # 0\n", + "\n", + "y = np.searchsorted(x, -1, side='right')\n", + "print(y) # 0\n", + "\n", + "y = np.searchsorted(x, 35)\n", + "print(y) # 8\n", + "\n", + "y = np.searchsorted(x, 35, side='right')\n", + "print(y) # 8\n", + "\n", + "y = np.searchsorted(x, 11)\n", + "print(y) # 4\n", + "\n", + "y = np.searchsorted(x, 11, side='right')\n", + "print(y) # 5\n", + "\n", + "y = np.searchsorted(x, 0)\n", + "print(y) # 0\n", + "\n", + "y = np.searchsorted(x, 0, side='right')\n", + "print(y) # 1\n", + "\n", + "y = np.searchsorted(x, 33)\n", + "print(y) # 7\n", + "\n", + "y = np.searchsorted(x, 33, side='right')\n", + "print(y) # 8\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([0, 1, 5, 9, 11, 18, 26, 33])\n", + "y = np.searchsorted(x, [-1, 0, 11, 15, 33, 35])\n", + "print(y) # [0 0 4 5 7 8]\n", + "\n", + "y = np.searchsorted(x, [-1, 0, 11, 15, 33, 35], side='right')\n", + "print(y) # [0 1 5 5 8 8]\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([0, 1, 5, 9, 11, 18, 26, 33])\n", + "np.random.shuffle(x)\n", + "print(x) # [33 1 9 18 11 26 0 5]\n", + "\n", + "x_sort = np.argsort(x)\n", + "print(x_sort) # [6 1 7 2 4 3 5 0]\n", + "\n", + "y = np.searchsorted(x, [-1, 0, 11, 15, 33, 35], sorter=x_sort)\n", + "print(y) # [0 0 4 5 7 8]\n", + "\n", + "y = np.searchsorted(x, [-1, 0, 11, 15, 33, 35], side='right', sorter=x_sort)\n", + "print(y) # [0 1 5 5 8 8]\n", + "```\n", + "\n", + "\n", + "---\n", + "## 计数\n", + "\n", + "- `numpy.count_nonzero(a, axis=None)` Counts the number of non-zero values in the array a.\n", + "\n", + "【例】返回数组中的非0元素个数。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.count_nonzero(np.eye(4))\n", + "print(x) # 4\n", + "\n", + "x = np.count_nonzero([[0, 1, 7, 0, 0], [3, 0, 0, 2, 19]])\n", + "print(x) # 5\n", + "\n", + "x = np.count_nonzero([[0, 1, 7, 0, 0], [3, 0, 0, 2, 19]], axis=0)\n", + "print(x) # [1 1 1 1 1]\n", + "\n", + "x = np.count_nonzero([[0, 1, 7, 0, 0], [3, 0, 0, 2, 19]], axis=1)\n", + "print(x) # [2 3]\n", + "```\n", + "\n", + "---\n", + "**参考文献**\n", + "\n", + "- https://blog.csdn.net/u013698770/article/details/54632047\n", + "- https://www.cnblogs.com/massquantity/p/8908859.html\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/10. 集合操作.ipynb b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/10. 集合操作.ipynb new file mode 100644 index 0000000..367ee93 --- /dev/null +++ b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/10. 集合操作.ipynb @@ -0,0 +1,246 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 集合操作\n", + "\n", + "## 构造集合\n", + "\n", + "- `numpy.unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None)` Find the unique elements of an array.\n", + " - `return_index=True` 表示返回新列表元素在旧列表中的位置。\n", + " - `return_inverse=True`表示返回旧列表元素在新列表中的位置。\n", + " - `return_counts=True`表示返回新列表元素在旧列表中出现的次数。\n", + " \n", + " \n", + "【例】找出数组中的唯一值并返回已排序的结果。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.unique([1, 1, 3, 2, 3, 3])\n", + "print(x) # [1 2 3]\n", + "\n", + "x = sorted(set([1, 1, 3, 2, 3, 3]))\n", + "print(x) # [1, 2, 3]\n", + "\n", + "x = np.array([[1, 1], [2, 3]])\n", + "u = np.unique(x)\n", + "print(u) # [1 2 3]\n", + "\n", + "x = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]])\n", + "y = np.unique(x, axis=0)\n", + "print(y)\n", + "# [[1 0 0]\n", + "# [2 3 4]]\n", + "\n", + "x = np.array(['a', 'b', 'b', 'c', 'a'])\n", + "u, index = np.unique(x, return_index=True)\n", + "print(u) # ['a' 'b' 'c']\n", + "print(index) # [0 1 3]\n", + "print(x[index]) # ['a' 'b' 'c']\n", + "\n", + "x = np.array([1, 2, 6, 4, 2, 3, 2])\n", + "u, index = np.unique(x, return_inverse=True)\n", + "print(u) # [1 2 3 4 6]\n", + "print(index) # [0 1 4 3 1 2 1]\n", + "print(u[index]) # [1 2 6 4 2 3 2]\n", + "\n", + "u, count = np.unique(x, return_counts=True)\n", + "print(u) # [1 2 3 4 6]\n", + "print(count) # [1 3 1 1 1]\n", + "```\n", + "\n", + "## 布尔运算\n", + "\n", + "- `numpy.in1d(ar1, ar2, assume_unique=False, invert=False)` Test whether each element of a 1-D array is also present in a second array.\n", + "\n", + "Returns a boolean array the same length as `ar1` that is True where an element of `ar1` is in `ar2` and False otherwise.\n", + "\n", + "【例】前面的数组是否包含于后面的数组,返回布尔值。返回的值是针对第一个参数的数组的,所以维数和第一个参数一致,布尔值与数组的元素位置也一一对应。\n", + "```python\n", + "import numpy as np\n", + "\n", + "test = np.array([0, 1, 2, 5, 0])\n", + "states = [0, 2]\n", + "mask = np.in1d(test, states)\n", + "print(mask) # [ True False True False True]\n", + "print(test[mask]) # [0 2 0]\n", + "\n", + "mask = np.in1d(test, states, invert=True)\n", + "print(mask) # [False True False True False]\n", + "print(test[mask]) # [1 5]\n", + "```\n", + "\n", + "\n", + "### 求两个集合的交集:\n", + "\n", + "- `numpy.intersect1d(ar1, ar2, assume_unique=False, return_indices=False)` Find the intersection of two arrays.\n", + "\n", + "Return the sorted, unique values that are in both of the input arrays.\n", + "\n", + "【例】求两个数组的唯一化+求交集+排序函数。\n", + "```python\n", + "import numpy as np\n", + "from functools import reduce\n", + "\n", + "x = np.intersect1d([1, 3, 4, 3], [3, 1, 2, 1])\n", + "print(x) # [1 3]\n", + "\n", + "x = np.array([1, 1, 2, 3, 4])\n", + "y = np.array([2, 1, 4, 6])\n", + "xy, x_ind, y_ind = np.intersect1d(x, y, return_indices=True)\n", + "print(x_ind) # [0 2 4]\n", + "print(y_ind) # [1 0 2]\n", + "print(xy) # [1 2 4]\n", + "print(x[x_ind]) # [1 2 4]\n", + "print(y[y_ind]) # [1 2 4]\n", + "\n", + "x = reduce(np.intersect1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))\n", + "print(x) # [3]\n", + "```\n", + "\n", + "### 求两个集合的并集:\n", + "\n", + "- `numpy.union1d(ar1, ar2)` Find the union of two arrays.\n", + "\n", + "Return the unique, sorted array of values that are in either of the two input arrays.\n", + "\n", + "【例】计算两个集合的并集,唯一化并排序。\n", + "```python\n", + "import numpy as np\n", + "from functools import reduce\n", + "\n", + "x = np.union1d([-1, 0, 1], [-2, 0, 2])\n", + "print(x) # [-2 -1 0 1 2]\n", + "x = reduce(np.union1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))\n", + "print(x) # [1 2 3 4 6]\n", + "'''\n", + "functools.reduce(function, iterable[, initializer])\n", + "将两个参数的 function 从左至右积累地应用到 iterable 的条目,以便将该可迭代对象缩减为单一的值。 例如,reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 是计算 ((((1+2)+3)+4)+5) 的值。 左边的参数 x 是积累值而右边的参数 y 则是来自 iterable 的更新值。 如果存在可选项 initializer,它会被放在参与计算的可迭代对象的条目之前,并在可迭代对象为空时作为默认值。 如果没有给出 initializer 并且 iterable 仅包含一个条目,则将返回第一项。\n", + "\n", + "大致相当于:\n", + "def reduce(function, iterable, initializer=None):\n", + " it = iter(iterable)\n", + " if initializer is None:\n", + " value = next(it)\n", + " else:\n", + " value = initializer\n", + " for element in it:\n", + " value = function(value, element)\n", + " return value\n", + "'''\n", + "```\n", + "\n", + "### 求两个集合的差集:\n", + "\n", + "- `numpy.setdiff1d(ar1, ar2, assume_unique=False)` Find the set difference of two arrays.\n", + "\n", + "\n", + "Return the unique values in `ar1` that are not in `ar2`.\n", + "\n", + "【例】集合的差,即元素存在于第一个函数不存在于第二个函数中。\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 2, 4, 1])\n", + "b = np.array([3, 4, 5, 6])\n", + "x = np.setdiff1d(a, b)\n", + "print(x) # [1 2]\n", + "```\n", + "\n", + "### 求两个集合的异或:\n", + "\n", + "- `setxor1d(ar1, ar2, assume_unique=False)` Find the set exclusive-or of two arrays.\n", + "\n", + "【例】集合的对称差,即两个集合的交集的补集。简言之,就是两个数组中各自独自拥有的元素的集合。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 2, 4, 1])\n", + "b = np.array([3, 4, 5, 6])\n", + "x = np.setxor1d(a, b)\n", + "print(x) # [1 2 5 6]\n", + "```\n", + "\n", + "\n", + "\n", + "---\n", + "**参考文献**\n", + "- https://www.jianshu.com/p/3bfe21aa1adb\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/练习-排序搜索计数,集合操作-答案.ipynb b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/练习-排序搜索计数,集合操作-答案.ipynb new file mode 100644 index 0000000..bfab1a1 --- /dev/null +++ b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/练习-排序搜索计数,集合操作-答案.ipynb @@ -0,0 +1,512 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 排序搜索计数" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**如何通过第n列对一个数组进行排序**\n", + "\n", + "【知识点:排序】\n", + "\n", + "- (提示: argsort)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T07:06:34.985841Z", + "start_time": "2020-09-15T07:06:34.567440Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 6 0]\n", + " [7 0 3]\n", + " [0 6 0]]\n" + ] + } + ], + "source": [ + "Z = np.random.randint(0,10,(3,3))\n", + "print (Z)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T07:06:35.022771Z", + "start_time": "2020-09-15T07:06:35.000801Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1 6 0]\n", + " [0 6 0]\n", + " [7 0 3]]\n" + ] + } + ], + "source": [ + "print (Z[Z[:,2].argsort()])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:43:15.537614Z", + "start_time": "2020-09-06T02:43:15.532628Z" + } + }, + "source": [ + "**从`arr`中提取所有奇数。**\n", + "\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何从一维数组中提取满足指定条件的元素?" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T07:06:35.384825Z", + "start_time": "2020-09-15T07:06:35.376847Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 3 5 7 9]\n", + "[1 3 5 7 9]\n" + ] + } + ], + "source": [ + "#【答案】\n", + "import numpy as np\n", + "\n", + "arr = np.arange(10)\n", + "\n", + "# 方法1\n", + "index = np.where(arr % 2 == 1)\n", + "print(arr[index])\n", + "# [1 3 5 7 9]\n", + "\n", + "# 方法2\n", + "x = arr[arr % 2 == 1]\n", + "print(x)\n", + "# [1 3 5 7 9]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**将`arr`中的偶数元素替换为0。**\n", + "\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何用numpy数组中的另一个值替换满足条件的元素项?" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T07:06:35.907995Z", + "start_time": "2020-09-15T07:06:35.903011Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1 0 3 0 5 0 7 0 9]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "arr = np.arange(10)\n", + "index = np.where(arr % 2 == 0)\n", + "arr[index] = 0\n", + "print(arr)\n", + "# [0 1 0 3 0 5 0 7 0 9]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**将 `arr` 中的所有偶数元素替换为0,而不改变arr。**\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何在不影响原始数组的情况下替换满足条件的元素项?" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T07:06:36.689514Z", + "start_time": "2020-09-15T07:06:36.608498Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0 1 0 3 0 5 0 7 0 9]\n", + "[0 1 2 3 4 5 6 7 8 9]\n", + "[0 1 0 3 0 5 0 7 0 9]\n", + "[0 1 2 3 4 5 6 7 8 9]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "arr = np.arange(10)\n", + "\n", + "# 方法1\n", + "x = np.where(arr % 2 == 0, 0, arr)\n", + "print(x)\n", + "# [0 1 0 3 0 5 0 7 0 9]\n", + "print(arr)\n", + "# [0 1 2 3 4 5 6 7 8 9]\n", + "\n", + "# 方法2\n", + "x = np.copy(arr)\n", + "x[x % 2 == 0] = 0\n", + "print(x)\n", + "# [0 1 0 3 0 5 0 7 0 9]\n", + "print(arr)\n", + "# [0 1 2 3 4 5 6 7 8 9]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:10:15.790588Z", + "start_time": "2020-09-06T03:10:15.785591Z" + } + }, + "source": [ + "**获取给定数组a中前5个最大值的位置。**\n", + "\n", + "- `a = np.random.uniform(1, 50, 20)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何从numpy数组中获取最大的n个值的位置?" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T07:06:37.223217Z", + "start_time": "2020-09-15T07:06:37.205278Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[27.62684215 14.64009987 21.80136195 42.39403048 1.23122395 6.95688692\n", + " 33.86670515 41.466785 7.69862289 29.17957314 44.67477576 11.25090398\n", + " 10.08108276 6.31046763 11.76517714 48.95256545 40.77247431 9.42510962\n", + " 40.99501269 14.42961361]\n", + "[ 4 13 5 8 17 12 11 14 19 1 2 0 9 6 16 18 7 3 10 15]\n", + "[18 7 3 10 15]\n", + "(array([ 3, 7, 10, 15, 18], dtype=int64),)\n", + "[18 7 3 10 15]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "a = np.random.uniform(1, 50, 20)\n", + "print(a)\n", + "# [27.62684215 14.64009987 21.80136195 42.39403048 1.23122395 6.95688692\n", + "# 33.86670515 41.466785 7.69862289 29.17957314 44.67477576 11.25090398\n", + "# 10.08108276 6.31046763 11.76517714 48.95256545 40.77247431 9.42510962\n", + "# 40.99501269 14.42961361]\n", + "\n", + "# 方法1\n", + "b = np.argsort(a)\n", + "print(b)\n", + "print(b[-5:])\n", + "# [18 7 3 10 15]\n", + "\n", + "# 方法2\n", + "b = np.sort(a)\n", + "b = np.where(a >= b[-5])\n", + "print(b)\n", + "# (array([ 3, 7, 10, 15, 18], dtype=int64),)\n", + "\n", + "# 方法3\n", + "b = np.argpartition(a, kth=-5)\n", + "print(b[-5:])\n", + "# [18 7 3 10 15]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:16:45.278429Z", + "start_time": "2020-09-06T03:16:45.274474Z" + } + }, + "source": [ + "**删除一维numpy数组中所有NaN值。**\n", + "\n", + "- `a = np.array([1, 2, 3, np.nan, 5, 6, 7, np.nan])`\n", + "\n", + "【知识点:逻辑函数、搜索】\n", + "- 如何删除numpy数组中的缺失值?" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T07:06:37.705909Z", + "start_time": "2020-09-15T07:06:37.699887Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1. 2. 3. 5. 6. 7.]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, np.nan, 5, 6, 7, np.nan])\n", + "b = np.isnan(a)\n", + "c = np.where(np.logical_not(b))\n", + "print(a[c])\n", + "# [1. 2. 3. 5. 6. 7.]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 集合操作" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:49:53.817130Z", + "start_time": "2020-09-06T02:49:53.812188Z" + } + }, + "source": [ + "**获取数组a和数组b之间的公共项。**\n", + "\n", + "- `a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])`\n", + "- `b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])`\n", + "\n", + "【知识点:集合操作】\n", + "- 如何获取两个numpy数组之间的公共项?" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T07:06:38.496578Z", + "start_time": "2020-09-15T07:06:38.489570Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2 4]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])\n", + "b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])\n", + "x = np.intersect1d(a, b)\n", + "print(x) # [2 4]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T02:50:45.262179Z", + "start_time": "2020-09-06T02:50:45.257192Z" + } + }, + "source": [ + "**从数组a中删除数组b中的所有项。**\n", + "- `a = np.array([1, 2, 3, 4, 5])`\n", + "- `b = np.array([5, 6, 7, 8, 9])`\n", + "\n", + "【知识点:集合操作】\n", + "- 如何从一个数组中删除存在于另一个数组中的项?" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T07:06:39.018110Z", + "start_time": "2020-09-15T07:06:38.996083Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1 2 3 4]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 4, 5])\n", + "b = np.array([5, 6, 7, 8, 9])\n", + "x = np.setdiff1d(a, b)\n", + "print(x) # [1 2 3 4]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "307.2px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/练习-排序搜索计数,集合操作.ipynb b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/练习-排序搜索计数,集合操作.ipynb new file mode 100644 index 0000000..2dad162 --- /dev/null +++ b/IntroductionToNumpy/numpy/task05-3天排序搜索计数及集合操作/练习-排序搜索计数,集合操作.ipynb @@ -0,0 +1,184 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 排序搜索计数" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **如何通过第n列对一个数组进行排序**\n", + "- `Z = np.random.randint(0,10,(3,3))`\n", + "\n", + "【知识点:排序】\n", + "\n", + "- (提示: argsort)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **从`arr`中提取所有奇数。**\n", + "\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何从一维数组中提取满足指定条件的元素?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **将`arr`中的偶数元素替换为0。**\n", + "\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何用numpy数组中的另一个值替换满足条件的元素项?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ** 将 `arr` 中的所有偶数元素替换为0,而不改变arr。**\n", + "- `arr = np.arange(10)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何在不影响原始数组的情况下替换满足条件的元素项?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **获取给定数组a中前5个最大值的位置。**\n", + "\n", + "- `a = np.random.uniform(1, 50, 20)`\n", + "\n", + "【知识点:搜索】\n", + "- 如何从numpy数组中获取最大的n个值的位置?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **删除一维numpy数组中所有NaN值。**\n", + "\n", + "- `a = np.array([1, 2, 3, np.nan, 5, 6, 7, np.nan])`\n", + "\n", + "【知识点:逻辑函数、搜索】\n", + "- 如何删除numpy数组中的缺失值?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 集合操作" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **获取数组a和数组b之间的公共项。**\n", + "\n", + "- `a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])`\n", + "- `b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])`\n", + "\n", + "【知识点:集合操作】\n", + "- 如何获取两个numpy数组之间的公共项?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### **从数组a中删除数组b中的所有项。**\n", + "- `a = np.array([1, 2, 3, 4, 5])`\n", + "- `b = np.array([5, 6, 7, 8, 9])`\n", + "\n", + "【知识点:集合操作】\n", + "- 如何从一个数组中删除存在于另一个数组中的项?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/线性代数/13. 线性代数.-练习题.ipynb b/IntroductionToNumpy/numpy/线性代数/13. 线性代数.-练习题.ipynb new file mode 100644 index 0000000..3e9e4ea --- /dev/null +++ b/IntroductionToNumpy/numpy/线性代数/13. 线性代数.-练习题.ipynb @@ -0,0 +1,230 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:20:09.947636Z", + "start_time": "2020-09-06T03:20:09.941689Z" + } + }, + "source": [ + "**计算两个数组a和数组b之间的欧氏距离。**\n", + "\n", + "- `a = np.array([1, 2, 3, 4, 5])`\n", + "- `b = np.array([4, 5, 6, 7, 8])`\n", + "\n", + "【知识点:数学函数、线性代数】\n", + "- 如何计算两个数组之间的欧式距离?" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:20:29.252448Z", + "start_time": "2020-09-06T03:20:29.247462Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6.708203932499369\n", + "6.708203932499369\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 4, 5])\n", + "b = np.array([4, 5, 6, 7, 8])\n", + "\n", + "# 方法1\n", + "d = np.sqrt(np.sum((a - b) ** 2))\n", + "print(d) # 6.708203932499369\n", + "\n", + "# 方法2\n", + "d = np.linalg.norm(a - b)\n", + "print(d) # 6.708203932499369" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**计算矩阵的行列式和矩阵的逆**" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:14:17.578966Z", + "start_time": "2020-09-14T09:14:17.574254Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[5, 0, 0, 0, 0],\n", + " [0, 5, 0, 0, 0],\n", + " [0, 0, 5, 0, 0],\n", + " [0, 0, 0, 5, 0],\n", + " [0, 0, 0, 0, 5]])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.diag([5,5,5,5,5])" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:14:06.174005Z", + "start_time": "2020-09-14T09:14:06.171012Z" + } + }, + "outputs": [], + "source": [ + " result=np.diag([5,5,5,5,5])" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:14:07.806217Z", + "start_time": "2020-09-14T09:14:07.800758Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3124.999999999999" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.linalg.det(result)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T09:16:30.223746Z", + "start_time": "2020-09-14T09:16:30.217896Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0.2, 0. , 0. , 0. , 0. ],\n", + " [0. , 0.2, 0. , 0. , 0. ],\n", + " [0. , 0. , 0.2, 0. , 0. ],\n", + " [0. , 0. , 0. , 0.2, 0. ],\n", + " [0. , 0. , 0. , 0. , 0.2]])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.linalg.inv(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/线性代数/13. 线性代数..ipynb b/IntroductionToNumpy/numpy/线性代数/13. 线性代数..ipynb new file mode 100644 index 0000000..7113315 --- /dev/null +++ b/IntroductionToNumpy/numpy/线性代数/13. 线性代数..ipynb @@ -0,0 +1,656 @@ +{ + "cells": [ + { + "attachments": { + "task13%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0-%E7%9F%A9%E9%98%B5%E7%9A%84%E8%8C%83%E6%95%B0-%E5%AF%B9%E5%BA%94%E5%85%AC%E5%BC%8F.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 线性代数\n", + "\n", + "Numpy 定义了 `matrix` 类型,使用该 `matrix` 类型创建的是矩阵对象,它们的加减乘除运算缺省采用矩阵方式计算,因此用法和Matlab十分类似。但是由于 NumPy 中同时存在 `ndarray` 和 `matrix` 对象,因此用户很容易将两者弄混。这有违 Python 的“显式优于隐式”的原则,因此官方并不推荐在程序中使用 `matrix`。在这里,我们仍然用 `ndarray` 来介绍。\n", + "\n", + "## 矩阵和向量积\n", + "\n", + "矩阵的定义、矩阵的加法、矩阵的数乘、矩阵的转置与二维数组完全一致,不再进行说明,但矩阵的乘法有不同的表示。\n", + "\n", + "- `numpy.dot(a, b[, out])`计算两个矩阵的乘积,如果是一维数组则是它们的内积。\n", + "\n", + "【例1】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4, 5])\n", + "y = np.array([2, 3, 4, 5, 6])\n", + "z = np.dot(x, y)\n", + "print(z) # 70\n", + "\n", + "x = np.array([[1, 2, 3], [3, 4, 5], [6, 7, 8]])\n", + "print(x)\n", + "# [[1 2 3]\n", + "# [3 4 5]\n", + "# [6 7 8]]\n", + "\n", + "y = np.array([[5, 4, 2], [1, 7, 9], [0, 4, 5]])\n", + "print(y)\n", + "# [[5 4 2]\n", + "# [1 7 9]\n", + "# [0 4 5]]\n", + "\n", + "z = np.dot(x, y)\n", + "print(z)\n", + "# [[ 7 30 35]\n", + "# [ 19 60 67]\n", + "# [ 37 105 115]]\n", + "\n", + "z = np.dot(y, x)\n", + "print(z)\n", + "# [[ 29 40 51]\n", + "# [ 76 93 110]\n", + "# [ 42 51 60]]\n", + "```\n", + "\n", + "注意:在线性代数里面讲的维数和数组的维数不同,如线代中提到的n维行向量在 Numpy 中是一维数组,而线性代数中的n维列向量在 Numpy 中是一个shape为(n, 1)的二维数组。\n", + "\n", + "---\n", + "## 矩阵特征值与特征向量\n", + "\n", + "- `numpy.linalg.eig(a)` 计算方阵的特征值和特征向量。\n", + "- `numpy.linalg.eigvals(a)` 计算方阵的特征值。\n", + "\n", + "【例1】求方阵的特征值特征向量\n", + "```python\n", + "import numpy as np\n", + "\n", + "# 创建一个对角矩阵!\n", + "x = np.diag((1, 2, 3)) \n", + "print(x)\n", + "# [[1 0 0]\n", + "# [0 2 0]\n", + "# [0 0 3]]\n", + "\n", + "print(np.linalg.eigvals(x))\n", + "# [1. 2. 3.]\n", + "\n", + "a, b = np.linalg.eig(x) \n", + "# 特征值保存在a中,特征向量保存在b中\n", + "print(a)\n", + "# [1. 2. 3.]\n", + "print(b)\n", + "# [[1. 0. 0.]\n", + "# [0. 1. 0.]\n", + "# [0. 0. 1.]]\n", + "\n", + "# 检验特征值与特征向量是否正确\n", + "for i in range(3): \n", + " if np.allclose(a[i] * b[:, i], np.dot(x, b[:, i])):\n", + " print('Right')\n", + " else:\n", + " print('Error')\n", + "# Right\n", + "# Right\n", + "# Right\n", + "```\n", + "\n", + "【例2】判断对称阵是否为正定阵(特征值是否全部为正)。\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.arange(16).reshape(4, 4)\n", + "print(A)\n", + "# [[ 0 1 2 3]\n", + "# [ 4 5 6 7]\n", + "# [ 8 9 10 11]\n", + "# [12 13 14 15]]\n", + "\n", + "A = A + A.T # 将方阵转换成对称阵\n", + "print(A)\n", + "# [[ 0 5 10 15]\n", + "# [ 5 10 15 20]\n", + "# [10 15 20 25]\n", + "# [15 20 25 30]]\n", + "\n", + "B = np.linalg.eigvals(A) # 求A的特征值\n", + "print(B)\n", + "# [ 6.74165739e+01 -7.41657387e+00 1.82694656e-15 -1.72637110e-15]\n", + "\n", + "# 判断是不是所有的特征值都大于0,用到了all函数,显然对称阵A不是正定的\n", + "if np.all(B > 0):\n", + " print('Yes')\n", + "else:\n", + " print('No')\n", + "# No\n", + "```\n", + "\n", + "\n", + "---\n", + "## 矩阵分解\n", + "\n", + "### **奇异值分解**\n", + "\n", + "有关奇异值分解的原理:[奇异值分解(SVD)及其应用](https://mp.weixin.qq.com/s/GNHPamltnqaUpGG9NhvWxg)\n", + "\n", + "- `u, s, v = numpy.linalg.svd(a, full_matrices=True, compute_uv=True, hermitian=False)`奇异值分解\n", + " - `a` 是一个形如(M,N)矩阵\n", + " - `full_matrices`的取值是为False或者True,默认值为True,这时`u`的大小为(M,M),`v`的大小为(N,N)。否则`u`的大小为(M,K),`v`的大小为(K,N) ,K=min(M,N)。\n", + " - `compute_uv`的取值是为False或者True,默认值为True,表示计算`u,s,v`。为False的时候只计算`s`。\n", + " - 总共有三个返回值`u,s,v`,`u`大小为(M,M),`s`大小为(M,N),`v`大小为(N,N),`a = u*s*v`。\n", + " - 其中`s`是对矩阵`a`的奇异值分解。`s`除了对角元素不为`0`,其他元素都为`0`,并且对角元素从大到小排列。`s`中有`n`个奇异值,一般排在后面的比较接近0,所以仅保留比较大的`r`个奇异值。 \n", + "\n", + "注:Numpy中返回的`v`是通常所谓奇异值分解`a=u*s*v'`中`v`的转置。\n", + "\n", + "【例1】\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.array([[4, 11, 14], [8, 7, -2]])\n", + "print(A)\n", + "# [[ 4 11 14]\n", + "# [ 8 7 -2]]\n", + "\n", + "u, s, vh = np.linalg.svd(A, full_matrices=False)\n", + "print(u.shape) # (2, 2)\n", + "print(u)\n", + "# [[-0.9486833 -0.31622777]\n", + "# [-0.31622777 0.9486833 ]]\n", + "\n", + "print(s.shape) # (2,)\n", + "print(np.diag(s))\n", + "# [[18.97366596 0. ]\n", + "# [ 0. 9.48683298]]\n", + "\n", + "print(vh.shape) # (2, 3)\n", + "print(vh)\n", + "# [[-0.33333333 -0.66666667 -0.66666667]\n", + "# [ 0.66666667 0.33333333 -0.66666667]]\n", + "\n", + "a = np.dot(u, np.diag(s))\n", + "a = np.dot(a, vh)\n", + "print(a)\n", + "# [[ 4. 11. 14.]\n", + "# [ 8. 7. -2.]]\n", + "```\n", + "\n", + "【例2】\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.array([[1, 1], [1, -2], [2, 1]])\n", + "print(A)\n", + "# [[ 1 1]\n", + "# [ 1 -2]\n", + "# [ 2 1]]\n", + "\n", + "u, s, vh = np.linalg.svd(A, full_matrices=False)\n", + "print(u.shape) # (3, 2)\n", + "print(u)\n", + "# [[-5.34522484e-01 -1.11022302e-16]\n", + "# [ 2.67261242e-01 -9.48683298e-01]\n", + "# [-8.01783726e-01 -3.16227766e-01]]\n", + "\n", + "print(s.shape) # (2,)\n", + "print(np.diag(s))\n", + "# [[2.64575131 0. ]\n", + "# [0. 2.23606798]]\n", + "\n", + "print(vh.shape) # (2, 2)\n", + "print(vh)\n", + "# [[-0.70710678 -0.70710678]\n", + "# [-0.70710678 0.70710678]]\n", + "\n", + "a = np.dot(u, np.diag(s))\n", + "a = np.dot(a, vh)\n", + "print(a)\n", + "# [[ 1. 1.]\n", + "# [ 1. -2.]\n", + "# [ 2. 1.]]\n", + "```\n", + "\n", + "### **QR分解**\n", + "\n", + "- `q,r = numpy.linalg.qr(a, mode='reduced')`计算矩阵`a`的QR分解。\n", + " - `a`是一个(M, N)的待分解矩阵。\n", + " - `mode = reduced`:返回(M, N)的列向量两两正交的矩阵`q`,和(N, N)的三角阵`r`(Reduced QR分解)。\n", + " - `mode = complete`:返回(M, M)的正交矩阵`q`,和(M, N)的三角阵`r`(Full QR分解)。\n", + "\n", + "【例1】\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.array([[2, -2, 3], [1, 1, 1], [1, 3, -1]])\n", + "print(A)\n", + "# [[ 2 -2 3]\n", + "# [ 1 1 1]\n", + "# [ 1 3 -1]]\n", + "\n", + "q, r = np.linalg.qr(A)\n", + "print(q.shape) # (3, 3)\n", + "print(q)\n", + "# [[-0.81649658 0.53452248 0.21821789]\n", + "# [-0.40824829 -0.26726124 -0.87287156]\n", + "# [-0.40824829 -0.80178373 0.43643578]]\n", + "\n", + "print(r.shape) # (3, 3)\n", + "print(r)\n", + "# [[-2.44948974 0. -2.44948974]\n", + "# [ 0. -3.74165739 2.13808994]\n", + "# [ 0. 0. -0.65465367]]\n", + "\n", + "print(np.dot(q, r))\n", + "# [[ 2. -2. 3.]\n", + "# [ 1. 1. 1.]\n", + "# [ 1. 3. -1.]]\n", + "\n", + "a = np.allclose(np.dot(q.T, q), np.eye(3))\n", + "print(a) # True\n", + "```\n", + "\n", + "【例2】\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.array([[1, 1], [1, -2], [2, 1]])\n", + "print(A)\n", + "# [[ 1 1]\n", + "# [ 1 -2]\n", + "# [ 2 1]]\n", + "\n", + "q, r = np.linalg.qr(A, mode='complete')\n", + "print(q.shape) # (3, 3)\n", + "print(q)\n", + "# [[-0.40824829 0.34503278 -0.84515425]\n", + "# [-0.40824829 -0.89708523 -0.16903085]\n", + "# [-0.81649658 0.27602622 0.50709255]]\n", + "\n", + "print(r.shape) # (3, 2)\n", + "print(r)\n", + "# [[-2.44948974 -0.40824829]\n", + "# [ 0. 2.41522946]\n", + "# [ 0. 0. ]]\n", + "\n", + "print(np.dot(q, r))\n", + "# [[ 1. 1.]\n", + "# [ 1. -2.]\n", + "# [ 2. 1.]]\n", + "\n", + "a = np.allclose(np.dot(q, q.T), np.eye(3))\n", + "print(a) # True\n", + "```\n", + "\n", + "【例3】\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.array([[1, 1], [1, -2], [2, 1]])\n", + "print(A)\n", + "# [[ 1 1]\n", + "# [ 1 -2]\n", + "# [ 2 1]]\n", + "\n", + "q, r = np.linalg.qr(A)\n", + "print(q.shape) # (3, 2)\n", + "print(q)\n", + "# [[-0.40824829 0.34503278]\n", + "# [-0.40824829 -0.89708523]\n", + "# [-0.81649658 0.27602622]]\n", + "\n", + "print(r.shape) # (2, 2)\n", + "print(r)\n", + "# [[-2.44948974 -0.40824829]\n", + "# [ 0. 2.41522946]]\n", + "\n", + "print(np.dot(q, r))\n", + "# [[ 1. 1.]\n", + "# [ 1. -2.]\n", + "# [ 2. 1.]]\n", + "\n", + "a = np.allclose(np.dot(q.T, q), np.eye(2))\n", + "print(a) # True (说明q为正交矩阵)\n", + "```\n", + "\n", + "### **Cholesky分解**\n", + "\n", + "- `L = numpy.linalg.cholesky(a)` 返回正定矩阵`a`的 Cholesky 分解`a = L*L.T`,其中`L`是下三角。\n", + "\n", + "【例1】\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.array([[1, 1, 1, 1], [1, 3, 3, 3],\n", + " [1, 3, 5, 5], [1, 3, 5, 7]])\n", + "print(A)\n", + "# [[1 1 1 1]\n", + "# [1 3 3 3]\n", + "# [1 3 5 5]\n", + "# [1 3 5 7]]\n", + "\n", + "print(np.linalg.eigvals(A))\n", + "# [13.13707118 1.6199144 0.51978306 0.72323135]\n", + "\n", + "L = np.linalg.cholesky(A)\n", + "print(L)\n", + "# [[1. 0. 0. 0. ]\n", + "# [1. 1.41421356 0. 0. ]\n", + "# [1. 1.41421356 1.41421356 0. ]\n", + "# [1. 1.41421356 1.41421356 1.41421356]]\n", + "\n", + "print(np.dot(L, L.T))\n", + "# [[1. 1. 1. 1.]\n", + "# [1. 3. 3. 3.]\n", + "# [1. 3. 5. 5.]\n", + "# [1. 3. 5. 7.]]\n", + "```\n", + "\n", + "\n", + "---\n", + "## 范数和其它数字\n", + "\n", + "\n", + "### **矩阵的范数**\n", + "\n", + "- `numpy.linalg.norm(x, ord=None, axis=None, keepdims=False)` 计算向量或者矩阵的范数。\n", + "\n", + "根据`ord`参数的不同,计算不同的范数:\n", + "![task13%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0-%E7%9F%A9%E9%98%B5%E7%9A%84%E8%8C%83%E6%95%B0-%E5%AF%B9%E5%BA%94%E5%85%AC%E5%BC%8F.png](attachment:task13%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0-%E7%9F%A9%E9%98%B5%E7%9A%84%E8%8C%83%E6%95%B0-%E5%AF%B9%E5%BA%94%E5%85%AC%E5%BC%8F.png)\n", + "\n", + "\n", + "\n", + "\n", + "【例1】求向量的范数。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1, 2, 3, 4])\n", + "\n", + "print(np.linalg.norm(x, ord=1)) \n", + "# 10.0\n", + "print(np.sum(np.abs(x))) \n", + "# 10\n", + "\n", + "print(np.linalg.norm(x, ord=2)) \n", + "# 5.477225575051661\n", + "print(np.sum(np.abs(x) ** 2) ** 0.5) \n", + "# 5.477225575051661\n", + "\n", + "print(np.linalg.norm(x, ord=-np.inf)) \n", + "# 1.0\n", + "print(np.min(np.abs(x))) \n", + "# 1\n", + "\n", + "print(np.linalg.norm(x, ord=np.inf)) \n", + "# 4.0\n", + "print(np.max(np.abs(x))) \n", + "# 4\n", + "```\n", + "\n", + "【例2】求矩阵的范数\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.array([[1, 2, 3, 4], [2, 3, 5, 8],\n", + " [1, 3, 5, 7], [3, 4, 7, 11]])\n", + "\n", + "print(A)\n", + "# [[ 1 2 3 4]\n", + "# [ 2 3 5 8]\n", + "# [ 1 3 5 7]\n", + "# [ 3 4 7 11]]\n", + "\n", + "print(np.linalg.norm(A, ord=1)) # 30.0\n", + "print(np.max(np.sum(A, axis=0))) # 30\n", + "\n", + "print(np.linalg.norm(A, ord=2)) \n", + "# 20.24345358700576\n", + "print(np.max(np.linalg.svd(A, compute_uv=False))) \n", + "# 20.24345358700576\n", + "\n", + "print(np.linalg.norm(A, ord=np.inf)) # 25.0\n", + "print(np.max(np.sum(A, axis=1))) # 25\n", + "\n", + "print(np.linalg.norm(A, ord='fro')) \n", + "# 20.273134932713294\n", + "print(np.sqrt(np.trace(np.dot(A.T, A)))) \n", + "# 20.273134932713294\n", + "```\n", + "\n", + "### **方阵的行列式**\n", + "\n", + "- `numpy.linalg.det(a)` 计算行列式。\n", + "\n", + "【例】计算行列式。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2], [3, 4]])\n", + "print(x)\n", + "# [[1 2]\n", + "# [3 4]]\n", + "\n", + "print(np.linalg.det(x))\n", + "# -2.0000000000000004\n", + "```\n", + "\n", + "### **矩阵的秩**\n", + "\n", + "- `numpy.linalg.matrix_rank(M, tol=None, hermitian=False)` 返回矩阵的秩。\n", + "\n", + "【例】计算矩阵的秩。\n", + "```python\n", + "import numpy as np\n", + "\n", + "I = np.eye(3) # 先创建一个单位阵\n", + "print(I)\n", + "# [[1. 0. 0.]\n", + "# [0. 1. 0.]\n", + "# [0. 0. 1.]]\n", + "\n", + "r = np.linalg.matrix_rank(I)\n", + "print(r) # 3\n", + "\n", + "I[1, 1] = 0 # 将该元素置为0\n", + "print(I)\n", + "# [[1. 0. 0.]\n", + "# [0. 0. 0.]\n", + "# [0. 0. 1.]]\n", + "\n", + "r = np.linalg.matrix_rank(I) # 此时秩变成2\n", + "print(r) # 2\n", + "```\n", + "\n", + "### **矩阵的迹**\n", + "\n", + "- `numpy.trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None)` 方阵的迹就是主对角元素之和。\n", + "\n", + "【例】计算方阵的迹。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[1, 2, 3], [3, 4, 5], [6, 7, 8]])\n", + "print(x)\n", + "# [[1 2 3]\n", + "# [3 4 5]\n", + "# [6 7 8]]\n", + "\n", + "y = np.array([[5, 4, 2], [1, 7, 9], [0, 4, 5]])\n", + "print(y)\n", + "# [[5 4 2]\n", + "# [1 7 9]\n", + "# [0 4 5]]\n", + "\n", + "print(np.trace(x)) # A的迹等于A.T的迹\n", + "# 13\n", + "print(np.trace(np.transpose(x)))\n", + "# 13\n", + "\n", + "print(np.trace(x + y)) # 和的迹 等于 迹的和\n", + "# 30\n", + "print(np.trace(x) + np.trace(y))\n", + "# 30\n", + "```\n", + "\n", + "\n", + "---\n", + "## 解方程和逆矩阵\n", + "\n", + "### **逆矩阵(inverse matrix)**\n", + "\n", + "设 A 是数域上的一个 n 阶矩阵,若在相同数域上存在另一个 n 阶矩阵 B,使得:`AB=BA=E`(E 为单位矩阵),则我们称 B 是 A 的逆矩阵,而 A 则被称为可逆矩阵。\n", + "\n", + "- `numpy.linalg.inv(a)` 计算矩阵`a`的逆矩阵(矩阵可逆的充要条件:`det(a) != 0`,或者`a`满秩)。\n", + "\n", + "\n", + "【例】计算矩阵的逆矩阵。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "A = np.array([[1, -2, 1], [0, 2, -1], [1, 1, -2]])\n", + "print(A)\n", + "# [[ 1 -2 1]\n", + "# [ 0 2 -1]\n", + "# [ 1 1 -2]]\n", + "\n", + "# 求A的行列式,不为零则存在逆矩阵\n", + "A_det = np.linalg.det(A) \n", + "print(A_det)\n", + "# -2.9999999999999996\n", + "\n", + "A_inverse = np.linalg.inv(A) # 求A的逆矩阵\n", + "print(A_inverse)\n", + "# [[ 1.00000000e+00 1.00000000e+00 -1.11022302e-16]\n", + "# [ 3.33333333e-01 1.00000000e+00 -3.33333333e-01]\n", + "# [ 6.66666667e-01 1.00000000e+00 -6.66666667e-01]]\n", + "\n", + "x = np.allclose(np.dot(A, A_inverse), np.eye(3))\n", + "print(x) # True\n", + "x = np.allclose(np.dot(A_inverse, A), np.eye(3))\n", + "print(x) # True\n", + "\n", + "A_companion = A_inverse * A_det # 求A的伴随矩阵\n", + "print(A_companion)\n", + "# [[-3.00000000e+00 -3.00000000e+00 3.33066907e-16]\n", + "# [-1.00000000e+00 -3.00000000e+00 1.00000000e+00]\n", + "# [-2.00000000e+00 -3.00000000e+00 2.00000000e+00]]\n", + "```\n", + "\n", + "\n", + "\n", + "### **求解线性方程组**\n", + "\n", + "- `numpy.linalg.solve(a, b)` 求解线性方程组或矩阵方程。\n", + "\n", + "\n", + "【例】求解线性矩阵方程\n", + "```python\n", + "# x + 2y + z = 7\n", + "# 2x - y + 3z = 7\n", + "# 3x + y + 2z =18\n", + "\n", + "import numpy as np\n", + "\n", + "A = np.array([[1, 2, 1], [2, -1, 3], [3, 1, 2]])\n", + "b = np.array([7, 7, 18])\n", + "x = np.linalg.solve(A, b)\n", + "print(x) # [ 7. 1. -2.]\n", + "\n", + "x = np.linalg.inv(A).dot(b)\n", + "print(x) # [ 7. 1. -2.]\n", + "\n", + "y = np.allclose(np.dot(A, x), b)\n", + "print(y) # True\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "---\n", + "**参考文献**\n", + "- https://www.cnblogs.com/moon1992/p/4960700.html\n", + "- https://www.cnblogs.com/moon1992/p/4948793.html\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "265.2px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/统计相关/12. 统计相关-练习题.ipynb b/IntroductionToNumpy/numpy/统计相关/12. 统计相关-练习题.ipynb new file mode 100644 index 0000000..7af0aff --- /dev/null +++ b/IntroductionToNumpy/numpy/统计相关/12. 统计相关-练习题.ipynb @@ -0,0 +1,258 @@ +{ + "cells": [ + { + "attachments": { + "image.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## y=X β\n", + "对于简单线性回归,向量计法等同于\n", + "![image.png](attachment:image.png)\n", + "给定X跟y我们可以使用 NumPy 库解出β值," + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-05T06:01:41.779628Z", + "start_time": "2020-09-05T06:01:41.773643Z" + } + }, + "outputs": [], + "source": [ + "from numpy . linalg import inv \n", + "from numpy import dot, transpose \n", + "X = [[1, 6, 2] , [1, 8, 1] , [1, 10, 0] , [1 , 14, 2] , [1, 18, 0]] \n", + "y = [[7] , [9] , [13] , [17.5] , [18]] " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-05T06:02:12.854939Z", + "start_time": "2020-09-05T06:02:12.850949Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1, 6, 2], [1, 8, 1], [1, 10, 0], [1, 14, 2], [1, 18, 0]]\n", + "[[7], [9], [13], [17.5], [18]]\n" + ] + } + ], + "source": [ + "print(X)\n", + "print(y)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-05T06:02:47.486171Z", + "start_time": "2020-09-05T06:02:47.416356Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1.1875 ]\n", + " [1.01041667]\n", + " [0.39583333]]\n" + ] + } + ], + "source": [ + "print(dot(inv(dot(transpose(X) , X)) , dot(transpose(X) , y))) " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-05T06:03:38.129940Z", + "start_time": "2020-09-05T06:03:38.124978Z" + } + }, + "source": [ + "NumPy 库也提供了一个最小二乘函数, 它能被用来更简洁地解出参数值" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-05T06:04:55.522309Z", + "start_time": "2020-09-05T06:04:55.433378Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1.1875 ]\n", + " [1.01041667]\n", + " [0.39583333]]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "F:\\dev\\anaconda\\envs\\python35\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.\n", + "To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.\n", + " \n" + ] + } + ], + "source": [ + "from numpy.linalg import lstsq\n", + "print(lstsq(X,y)[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:14:01.752078Z", + "start_time": "2020-09-06T03:14:01.747126Z" + } + }, + "source": [ + "\n", + "**计算给定数组中每行的最大值。**\n", + "\n", + "- `a = np.random.randint(1, 10, [5, 3])`\n", + "\n", + "【知识点:统计相关】\n", + "- 如何在二维numpy数组的每一行中找到最大值?" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:14:22.429480Z", + "start_time": "2020-09-06T03:14:22.424495Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[9 9 4]\n", + " [8 8 1]\n", + " [5 3 6]\n", + " [3 3 3]\n", + " [2 1 9]]\n", + "[9 8 6 3 9]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "np.random.seed(100)\n", + "a = np.random.randint(1, 10, [5, 3])\n", + "print(a)\n", + "# [[9 9 4]\n", + "# [8 8 1]\n", + "# [5 3 6]\n", + "# [3 3 3]\n", + "# [2 1 9]]\n", + "\n", + "b = np.amax(a, axis=1)\n", + "print(b)\n", + "# [9 8 6 3 9]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/统计相关/12. 统计相关.ipynb b/IntroductionToNumpy/numpy/统计相关/12. 统计相关.ipynb new file mode 100644 index 0000000..b510006 --- /dev/null +++ b/IntroductionToNumpy/numpy/统计相关/12. 统计相关.ipynb @@ -0,0 +1,452 @@ +{ + "cells": [ + { + "attachments": { + "task12%E7%BB%9F%E8%AE%A1%E7%9B%B8%E5%85%B3-%E5%8D%8F%E6%96%B9%E5%B7%AE%E7%9F%A9%E9%98%B5-%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 统计相关\n", + "\n", + "## 次序统计\n", + "\n", + "### 计算最小值\n", + "- `numpy.amin(a[, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue, where=np._NoValue])`Return the minimum of an array or minimum along an axis.\n", + "\n", + " \n", + " 【例】计算最小值\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.amin(x)\n", + "print(y) # 11\n", + "\n", + "y = np.amin(x, axis=0)\n", + "print(y) # [11 12 13 14 15]\n", + "\n", + "y = np.amin(x, axis=1)\n", + "print(y) # [11 16 21 26 31]\n", + "```\n", + "### 计算最大值\n", + "- `numpy.amax(a[, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue, where=np._NoValue])`Return the maximum of an array or maximum along an axis.\n", + "\n", + "\n", + "【例】计算最大值\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.amax(x)\n", + "print(y) # 35\n", + "\n", + "y = np.amax(x, axis=0)\n", + "print(y) # [31 32 33 34 35]\n", + "\n", + "y = np.amax(x, axis=1)\n", + "print(y) # [15 20 25 30 35]\n", + "```\n", + "### 计算极差\n", + "- `numpy.ptp(a, axis=None, out=None, keepdims=np._NoValue)` Range of values (maximum - minimum) along an axis. The name of the function comes from the acronym for 'peak to peak'.\n", + "\n", + "【例】计算极差\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200623)\n", + "x = np.random.randint(0, 20, size=[4, 5])\n", + "print(x)\n", + "# [[10 2 1 1 16]\n", + "# [18 11 10 14 10]\n", + "# [11 1 9 18 8]\n", + "# [16 2 0 15 16]]\n", + "\n", + "print(np.ptp(x)) # 18\n", + "print(np.ptp(x, axis=0)) # [ 8 10 10 17 8]\n", + "print(np.ptp(x, axis=1)) # [15 8 17 16]\n", + "```\n", + "### 计算分位数\n", + "\n", + "- `numpy.percentile(a, q, axis=None, out=None, overwrite_input=False, interpolation='linear', keepdims=False)` Compute the q-th percentile of the data along the specified axis. Returns the q-th percentile(s) of the array elements.\n", + " - a:array,用来算分位数的对象,可以是多维的数组。\n", + " - q:介于0-100的float,用来计算是几分位的参数,如四分之一位就是25,如要算两个位置的数就[25,75]。\n", + " - axis:坐标轴的方向,一维的就不用考虑了,多维的就用这个调整计算的维度方向,取值范围0/1。\n", + "\n", + "\n", + "【例】计算分位数\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200623)\n", + "x = np.random.randint(0, 20, size=[4, 5])\n", + "print(x)\n", + "# [[10 2 1 1 16]\n", + "# [18 11 10 14 10]\n", + "# [11 1 9 18 8]\n", + "# [16 2 0 15 16]]\n", + "\n", + "print(np.percentile(x, [25, 50])) \n", + "# [ 2. 10.]\n", + "\n", + "print(np.percentile(x, [25, 50], axis=0))\n", + "# [[10.75 1.75 0.75 10.75 9.5 ]\n", + "# [13.5 2. 5. 14.5 13. ]]\n", + "\n", + "print(np.percentile(x, [25, 50], axis=1))\n", + "# [[ 1. 10. 8. 2.]\n", + "# [ 2. 11. 9. 15.]]\n", + "```\n", + "\n", + "\n", + "---\n", + "## 均值与方差\n", + "\n", + "### 计算中位数\n", + "- `numpy.median(a, axis=None, out=None, overwrite_input=False, keepdims=False)` Compute the median along the specified axis. Returns the median of the array elements.\n", + "\n", + "【例】计算中位数\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200623)\n", + "x = np.random.randint(0, 20, size=[4, 5])\n", + "print(x)\n", + "# [[10 2 1 1 16]\n", + "# [18 11 10 14 10]\n", + "# [11 1 9 18 8]\n", + "# [16 2 0 15 16]]\n", + "print(np.percentile(x, 50))\n", + "print(np.median(x))\n", + "# 10.0\n", + "\n", + "print(np.percentile(x, 50, axis=0))\n", + "print(np.median(x, axis=0))\n", + "# [13.5 2. 5. 14.5 13. ]\n", + "\n", + "print(np.percentile(x, 50, axis=1))\n", + "print(np.median(x, axis=1))\n", + "# [ 2. 11. 9. 15.]\n", + "```\n", + "\n", + "### 计算平均值\n", + "\n", + "- `numpy.mean(a[, axis=None, dtype=None, out=None, keepdims=np._NoValue)])`Compute the arithmetic mean along the specified axis.\n", + "\n", + "【例】计算平均值(沿轴的元素的总和除以元素的数量)。\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.mean(x)\n", + "print(y) # 23.0\n", + "\n", + "y = np.mean(x, axis=0)\n", + "print(y) # [21. 22. 23. 24. 25.]\n", + "\n", + "y = np.mean(x, axis=1)\n", + "print(y) # [13. 18. 23. 28. 33.]\n", + "```\n", + "### 计算加权平均值\n", + "- `numpy.average(a[, axis=None, weights=None, returned=False])`Compute the weighted average along the specified axis.\n", + "\n", + "\n", + "`mean`和`average`都是计算均值的函数,在不指定权重的时候`average`和`mean`是一样的。指定权重后,`average`可以计算加权平均值。\n", + "\n", + "【例】计算加权平均值(将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。)\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.average(x)\n", + "print(y) # 23.0\n", + "\n", + "y = np.average(x, axis=0)\n", + "print(y) # [21. 22. 23. 24. 25.]\n", + "\n", + "y = np.average(x, axis=1)\n", + "print(y) # [13. 18. 23. 28. 33.]\n", + "\n", + "\n", + "y = np.arange(1, 26).reshape([5, 5])\n", + "print(y)\n", + "# [[ 1 2 3 4 5]\n", + "# [ 6 7 8 9 10]\n", + "# [11 12 13 14 15]\n", + "# [16 17 18 19 20]\n", + "# [21 22 23 24 25]]\n", + "\n", + "z = np.average(x, weights=y)\n", + "print(z) # 27.0\n", + "\n", + "z = np.average(x, axis=0, weights=y)\n", + "print(z)\n", + "# [25.54545455 26.16666667 26.84615385 27.57142857 28.33333333]\n", + "\n", + "z = np.average(x, axis=1, weights=y)\n", + "print(z)\n", + "# [13.66666667 18.25 23.15384615 28.11111111 33.08695652]\n", + "```\n", + "### 计算方差\n", + "- `numpy.var(a[, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue])`Compute the variance along the specified axis.\n", + " - ddof=0:是“Delta Degrees of Freedom”,表示自由度的个数。\n", + "\n", + "要注意方差和样本方差的无偏估计,方差公式中分母上是`n`;样本方差无偏估计公式中分母上是`n-1`(`n`为样本个数)。\n", + "\n", + "[证明的链接](https://blog.csdn.net/SoftPoeter/article/details/78273117?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf) \n", + "\n", + "【例】计算方差\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.var(x)\n", + "print(y) # 52.0\n", + "y = np.mean((x - np.mean(x)) ** 2)\n", + "print(y) # 52.0\n", + "\n", + "y = np.var(x, ddof=1)\n", + "print(y) # 54.166666666666664\n", + "y = np.sum((x - np.mean(x)) ** 2) / (x.size - 1)\n", + "print(y) # 54.166666666666664\n", + "\n", + "y = np.var(x, axis=0)\n", + "print(y) # [50. 50. 50. 50. 50.]\n", + "\n", + "y = np.var(x, axis=1)\n", + "print(y) # [2. 2. 2. 2. 2.]\n", + "```\n", + "### 计算标准差\n", + "\n", + "- `numpy.std(a[, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue])`Compute the standard deviation along the specified axis.\n", + "\n", + "标准差是一组数据平均值分散程度的一种度量,是方差的算术平方根。\n", + "\n", + "\n", + "【例】计算标准差\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([[11, 12, 13, 14, 15],\n", + " [16, 17, 18, 19, 20],\n", + " [21, 22, 23, 24, 25],\n", + " [26, 27, 28, 29, 30],\n", + " [31, 32, 33, 34, 35]])\n", + "y = np.std(x)\n", + "print(y) # 7.211102550927978\n", + "y = np.sqrt(np.var(x))\n", + "print(y) # 7.211102550927978\n", + "\n", + "y = np.std(x, axis=0)\n", + "print(y)\n", + "# [7.07106781 7.07106781 7.07106781 7.07106781 7.07106781]\n", + "\n", + "y = np.std(x, axis=1)\n", + "print(y)\n", + "# [1.41421356 1.41421356 1.41421356 1.41421356 1.41421356]\n", + "```\n", + "\n", + "---\n", + "## 相关\n", + "### 计算协方差矩阵\n", + "\n", + "![task12%E7%BB%9F%E8%AE%A1%E7%9B%B8%E5%85%B3-%E5%8D%8F%E6%96%B9%E5%B7%AE%E7%9F%A9%E9%98%B5-%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F.png](attachment:task12%E7%BB%9F%E8%AE%A1%E7%9B%B8%E5%85%B3-%E5%8D%8F%E6%96%B9%E5%B7%AE%E7%9F%A9%E9%98%B5-%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F.png)\n", + "\n", + "- `numpy.cov(m, y=None, rowvar=True, bias=False, ddof=None, fweights=None,aweights=None)` Estimate a covariance matrix, given data and weights.\n", + "\n", + "【例】计算协方差矩阵\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = [1, 2, 3, 4, 6]\n", + "y = [0, 2, 5, 6, 7]\n", + "print(np.cov(x)) # 3.7 #样本方差\n", + "print(np.cov(y)) # 8.5 #样本方差\n", + "print(np.cov(x, y))\n", + "# [[3.7 5.25]\n", + "# [5.25 8.5 ]]\n", + "\n", + "print(np.var(x)) # 2.96 #方差\n", + "print(np.var(x, ddof=1)) # 3.7 #样本方差\n", + "print(np.var(y)) # 6.8 #方差\n", + "print(np.var(y, ddof=1)) # 8.5 #样本方差\n", + "\n", + "z = np.mean((x - np.mean(x)) * (y - np.mean(y))) #协方差\n", + "print(z) # 4.2\n", + "\n", + "z = np.sum((x - np.mean(x)) * (y - np.mean(y))) / (len(x) - 1) #样本协方差\n", + "print(z) # 5.25\n", + "\n", + "z = np.dot(x - np.mean(x), y - np.mean(y)) / (len(x) - 1) #样本协方差 \n", + "print(z) # 5.25\n", + "```\n", + "\n", + "### 计算相关系数\n", + "- `numpy.corrcoef(x, y=None, rowvar=True, bias=np._NoValue, ddof=np._NoValue)` Return Pearson product-moment correlation coefficients.\n", + "\n", + "理解了`np.cov()`函数之后,很容易理解`np.correlate()`,二者参数几乎一模一样。\n", + "\n", + "`np.cov()`描述的是两个向量协同变化的程度,它的取值可能非常大,也可能非常小,这就导致没法直观地衡量二者协同变化的程度。相关系数实际上是正则化的协方差,`n`个变量的相关系数形成一个`n`维方阵。\n", + "\n", + "【例】计算相关系数\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200623)\n", + "x, y = np.random.randint(0, 20, size=(2, 4))\n", + "\n", + "print(x) # [10 2 1 1]\n", + "print(y) # [16 18 11 10]\n", + "\n", + "z = np.corrcoef(x, y)\n", + "print(z)\n", + "# [[1. 0.48510096]\n", + "# [0.48510096 1. ]]\n", + "\n", + "a = np.dot(x - np.mean(x), y - np.mean(y))\n", + "b = np.sqrt(np.dot(x - np.mean(x), x - np.mean(x)))\n", + "c = np.sqrt(np.dot(y - np.mean(y), y - np.mean(y)))\n", + "print(a / (b * c)) # 0.4851009629263671\n", + "```\n", + "\n", + "---\n", + "## 直方图\n", + "\n", + "- `numpy.digitize(x, bins, right=False)`Return the indices of the bins to which each value in input array belongs.\n", + " - x:numpy数组\n", + " - bins:一维单调数组,必须是升序或者降序\n", + " - right:间隔是否包含最右\n", + " - 返回值:x在bins中的位置。\n", + "\n", + "【例】\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([0.2, 6.4, 3.0, 1.6])\n", + "bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0])\n", + "inds = np.digitize(x, bins)\n", + "print(inds) # [1 4 3 2]\n", + "for n in range(x.size):\n", + " print(bins[inds[n] - 1], \"<=\", x[n], \"<\", bins[inds[n]])\n", + "\n", + "# 0.0 <= 0.2 < 1.0\n", + "# 4.0 <= 6.4 < 10.0\n", + "# 2.5 <= 3.0 < 4.0\n", + "# 1.0 <= 1.6 < 2.5\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "x = np.array([1.2, 10.0, 12.4, 15.5, 20.])\n", + "bins = np.array([0, 5, 10, 15, 20])\n", + "inds = np.digitize(x, bins, right=True)\n", + "print(inds) # [1 2 3 4 4]\n", + "\n", + "inds = np.digitize(x, bins, right=False)\n", + "print(inds) # [1 3 3 4 5]\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "279.2px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/输入输出/14. 输入和输出-练习题.ipynb b/IntroductionToNumpy/numpy/输入输出/14. 输入和输出-练习题.ipynb new file mode 100644 index 0000000..104b206 --- /dev/null +++ b/IntroductionToNumpy/numpy/输入输出/14. 输入和输出-练习题.ipynb @@ -0,0 +1,229 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:05:42.613206Z", + "start_time": "2020-09-06T03:05:42.609217Z" + } + }, + "source": [ + "**只打印或显示numpy数组rand_arr的小数点后3位。**\n", + "\n", + "- `rand_arr = np.random.random([5, 3])`\n", + "\n", + "【知识点:输入和输出】\n", + "- 如何在numpy数组中只打印小数点后三位?" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:06:03.840763Z", + "start_time": "2020-09-06T03:06:03.834778Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0.25106063 0.32735642 0.17623774]\n", + " [0.85566173 0.11420437 0.53735783]\n", + " [0.82253612 0.07625331 0.9358199 ]\n", + " [0.97268875 0.91794448 0.61845404]\n", + " [0.58615827 0.28096349 0.88048956]]\n", + "[[0.251 0.327 0.176]\n", + " [0.856 0.114 0.537]\n", + " [0.823 0.076 0.936]\n", + " [0.973 0.918 0.618]\n", + " [0.586 0.281 0.88 ]]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "rand_arr = np.random.random([5, 3])\n", + "print(rand_arr)\n", + "# [[0.33033427 0.05538836 0.05947305]\n", + "# [0.36199439 0.48844555 0.26309599]\n", + "# [0.05361816 0.71539075 0.60645637]\n", + "# [0.95000384 0.31424729 0.41032467]\n", + "# [0.36082793 0.50101268 0.6306832 ]]\n", + "\n", + "np.set_printoptions(precision=3)\n", + "print(rand_arr)\n", + "# [[0.33 0.055 0.059]\n", + "# [0.362 0.488 0.263]\n", + "# [0.054 0.715 0.606]\n", + "# [0.95 0.314 0.41 ]\n", + "# [0.361 0.501 0.631]]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:06:22.855956Z", + "start_time": "2020-09-06T03:06:22.850970Z" + } + }, + "source": [ + "**将numpy数组a中打印的项数限制为最多6个元素。**\n", + "\n", + "【知识点:输入和输出】\n", + "- 如何限制numpy数组输出中打印的项目数?" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:06:51.128200Z", + "start_time": "2020-09-06T03:06:51.123215Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]\n", + "[ 0 1 2 ... 12 13 14]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.arange(15)\n", + "print(a)\n", + "# [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]\n", + "np.set_printoptions(threshold=6)\n", + "print(a)\n", + "# [ 0 1 2 ... 12 13 14]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:07:14.131621Z", + "start_time": "2020-09-06T03:07:14.126608Z" + } + }, + "source": [ + "**打印完整的numpy数组a而不中断。**\n", + "\n", + "【知识点:输入和输出】\n", + "- 如何打印完整的numpy数组而不中断?" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-06T03:07:47.868079Z", + "start_time": "2020-09-06T03:07:47.863126Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 0 1 2 ... 12 13 14]\n", + "[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = np.arange(15)\n", + "np.set_printoptions(threshold=6)\n", + "print(a)\n", + "# [ 0 1 2 ... 12 13 14]\n", + "np.set_printoptions(threshold=np.iinfo(np.int).max)\n", + "print(a)\n", + "# [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IntroductionToNumpy/numpy/输入输出/14. 输入和输出.ipynb b/IntroductionToNumpy/numpy/输入输出/14. 输入和输出.ipynb new file mode 100644 index 0000000..154c3a9 --- /dev/null +++ b/IntroductionToNumpy/numpy/输入输出/14. 输入和输出.ipynb @@ -0,0 +1,372 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 输入和输出\n", + "\n", + "\n", + "\n", + "## numpy 二进制文件\n", + "\n", + "`save()`、`savez()`和`load()`函数以 numpy 专用的二进制类型(npy、npz)保存和读取数据,这三个函数会自动处理ndim、dtype、shape等信息,使用它们读写数组非常方便,但是`save()`输出的文件很难与其它语言编写的程序兼容。\n", + "\n", + "npy格式:以二进制的方式存储文件,在二进制文件第一行以文本形式保存了数据的元信息(ndim,dtype,shape等),可以用二进制工具查看内容。\n", + "\n", + "npz格式:以压缩打包的方式存储文件,可以用压缩软件解压。\n", + "\n", + "\n", + "- `numpy.save(file, arr, allow_pickle=True, fix_imports=True)` Save an array to a binary file in NumPy `.npy` format.\n", + "- `numpy.load(file, mmap_mode=None, allow_pickle=False, fix_imports=True, encoding='ASCII')` Load arrays or pickled objects from ``.npy``, ``.npz`` or pickled files.\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "outfile = r'.\\test.npy'\n", + "np.random.seed(20200619)\n", + "x = np.random.uniform(0, 1, [3, 5])\n", + "np.save(outfile, x)\n", + "y = np.load(outfile)\n", + "print(y)\n", + "# [[0.01123594 0.66790705 0.50212171 0.7230908 0.61668256]\n", + "# [0.00668332 0.1234096 0.96092409 0.67925305 0.38596837]\n", + "# [0.72342998 0.26258324 0.24318845 0.98795012 0.77370715]]\n", + "```\n", + "\n", + "- `numpy.savez(file, *args, **kwds)` Save several arrays into a single file in uncompressed `.npz` format.\n", + "\n", + "`savez()`第一个参数是文件名,其后的参数都是需要保存的数组,也可以使用关键字参数为数组起一个名字,非关键字参数传递的数组会自动起名为`arr_0, arr_1, …`。\n", + "\n", + "`savez()`输出的是一个压缩文件(扩展名为npz),其中每个文件都是一个`save()`保存的npy文件,文件名对应于数组名。`load()`自动识别npz文件,并且返回一个类似于字典的对象,可以通过数组名作为关键字获取数组的内容。\n", + "\n", + "【例】将多个数组保存到一个文件,可以使用`numpy.savez()`函数。\n", + "```python\n", + "import numpy as np\n", + "\n", + "outfile = r'.\\test.npz'\n", + "x = np.linspace(0, np.pi, 5)\n", + "y = np.sin(x)\n", + "z = np.cos(x)\n", + "np.savez(outfile, x, y, z_d=z)\n", + "data = np.load(outfile)\n", + "np.set_printoptions(suppress=True)\n", + "print(data.files) \n", + "# ['z_d', 'arr_0', 'arr_1']\n", + "\n", + "print(data['arr_0'])\n", + "# [0. 0.78539816 1.57079633 2.35619449 3.14159265]\n", + "\n", + "print(data['arr_1'])\n", + "# [0. 0.70710678 1. 0.70710678 0. ]\n", + "\n", + "print(data['z_d'])\n", + "# [ 1. 0.70710678 0. -0.70710678 -1. ]\n", + "```\n", + "\n", + "用解压软件打开 test.npz 文件,会发现其中有三个文件:`arr_0.npy,arr_1.npy,z_d.npy`,其中分别保存着数组`x,y,z`的内容。\n", + "\n", + "\n", + "---\n", + "## 文本文件\n", + "`savetxt()`,`loadtxt()`和`genfromtxt()`函数用来存储和读取文本文件(如TXT,CSV等)。`genfromtxt()`比`loadtxt()`更加强大,可对缺失数据进行处理。\n", + "\n", + "- `numpy.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\\n', header='', footer='', comments='# ', encoding=None)` Save an array to a text file.\n", + " - fname:文件路径\n", + " - X:存入文件的数组。\n", + " - fmt:写入文件中每个元素的字符串格式,默认'%.18e'(保留18位小数的浮点数形式)。\n", + " - delimiter:分割字符串,默认以空格分隔。\n", + "\n", + "\n", + "- `numpy.loadtxt(fname, dtype=float, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding='bytes', max_rows=None)` Load data from a text file. \n", + " - fname:文件路径。\n", + " - dtype:数据类型,默认为float。\n", + " - comments: 字符串或字符串组成的列表,默认为# , 表示注释字符集开始的标志。\n", + " - skiprows:跳过多少行,一般跳过第一行表头。\n", + " - usecols:元组(元组内数据为列的数值索引), 用来指定要读取数据的列(第一列为0)。\n", + " - unpack:当加载多列数据时是否需要将数据列进行解耦赋值给不同的变量。\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "【例】写入和读出TXT文件。\n", + "```python\n", + "import numpy as np\n", + "\n", + "outfile = r'.\\test.txt'\n", + "x = np.arange(0, 10).reshape(2, -1)\n", + "np.savetxt(outfile, x)\n", + "y = np.loadtxt(outfile)\n", + "print(y)\n", + "# [[0. 1. 2. 3. 4.]\n", + "# [5. 6. 7. 8. 9.]]\n", + "```\n", + "\n", + "test.txt文件如下:\n", + "\n", + "```python\n", + "0.000000000000000000e+00 1.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00 4.000000000000000000e+00\n", + "5.000000000000000000e+00 6.000000000000000000e+00 7.000000000000000000e+00 8.000000000000000000e+00 9.000000000000000000e+00\n", + "```\n", + "\n", + "\n", + "【例】写入和读出CSV文件。\n", + "```python\n", + "import numpy as np\n", + "\n", + "outfile = r'.\\test.csv'\n", + "x = np.arange(0, 10, 0.5).reshape(4, -1)\n", + "np.savetxt(outfile, x, fmt='%.3f', delimiter=',')\n", + "y = np.loadtxt(outfile, delimiter=',')\n", + "print(y)\n", + "# [[0. 0.5 1. 1.5 2. ]\n", + "# [2.5 3. 3.5 4. 4.5]\n", + "# [5. 5.5 6. 6.5 7. ]\n", + "# [7.5 8. 8.5 9. 9.5]]\n", + "```\n", + "\n", + "test.csv文件如下:\n", + "```python\n", + "0.000,0.500,1.000,1.500,2.000\n", + "2.500,3.000,3.500,4.000,4.500\n", + "5.000,5.500,6.000,6.500,7.000\n", + "7.500,8.000,8.500,9.000,9.500\n", + "```\n", + "\n", + "\n", + "\n", + "`genfromtxt()`是面向结构数组和缺失数据处理的。\n", + "\n", + "- `numpy.genfromtxt(fname, dtype=float, comments='#', delimiter=None, skip_header=0, skip_footer=0, converters=None, missing_values=None, filling_values=None, usecols=None, names=None, excludelist=None, deletechars=''.join(sorted(NameValidator.defaultdeletechars)), replace_space='_', autostrip=False, case_sensitive=True, defaultfmt=\"f%i\", unpack=None, usemask=False, loose=True, invalid_raise=True, max_rows=None, encoding='bytes')` Load data from a text file, with missing values handled as specified.\n", + " - names:设置为True时,程序将把第一行作为列名称。\n", + "\n", + "\n", + "data.csv文件如下:\n", + "```python\n", + "id,value1,value2,value3\n", + "1,123,1.4,23\n", + "2,110,0.5,18\n", + "3,164,2.1,19\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "outfile = r'.\\data.csv'\n", + "x = np.loadtxt(outfile, delimiter=',', skiprows=1)\n", + "print(x)\n", + "# [[ 1. 123. 1.4 23. ]\n", + "# [ 2. 110. 0.5 18. ]\n", + "# [ 3. 164. 2.1 19. ]]\n", + "\n", + "x = np.loadtxt(outfile, delimiter=',', skiprows=1, usecols=(1, 2))\n", + "print(x)\n", + "# [[123. 1.4]\n", + "# [110. 0.5]\n", + "# [164. 2.1]]\n", + "\n", + "val1, val2 = np.loadtxt(outfile, delimiter=',', skiprows=1, usecols=(1, 2), unpack=True)\n", + "print(val1) # [123. 110. 164.]\n", + "print(val2) # [1.4 0.5 2.1]\n", + "```\n", + "\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "outfile = r'.\\data.csv'\n", + "x = np.genfromtxt(outfile, delimiter=',', names=True)\n", + "print(x)\n", + "# [(1., 123., 1.4, 23.) (2., 110., 0.5, 18.) (3., 164., 2.1, 19.)]\n", + "\n", + "print(type(x)) \n", + "# \n", + "\n", + "print(x.dtype)\n", + "# [('id', '\n", + "\n", + "print(x.dtype)\n", + "# [('id', '= 0)) # True\n", + "print(np.all(x < 100)) # True\n", + "y = (np.sum(x < 50) - np.sum(x < 10)) / size\n", + "print(y) # 0.40144\n", + "\n", + "plt.hist(x, bins=20)\n", + "plt.show()\n", + "\n", + "a = stats.uniform.cdf(10, 0, 100)\n", + "b = stats.uniform.cdf(50, 0, 100)\n", + "print(b - a) # 0.4\n", + "```\n", + "\n", + "![](https://img-blog.csdnimg.cn/20200614175837513.png)\n", + "\n", + "作为`uniform()`的特列,可以得到`[0,1)`之间的均匀分布的随机数。\n", + "\n", + "- `numpy.random.rand(d0, d1, ..., dn)` Random values in a given shape.\n", + "\n", + "\n", + "\n", + "Create an array of the given shape and populate it with random samples from a uniform distribution over `[0, 1)`.\n", + "\n", + "\n", + "\n", + "【例】根据指定大小产生[0,1)之间均匀分布的随机数。\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200614)\n", + "print(np.random.rand())\n", + "# 0.7594819171852776\n", + "\n", + "print(np.random.rand(5))\n", + "# [0.75165827 0.16552651 0.0538581 0.46671446 0.89076925]\n", + "\n", + "print(np.random.rand(4, 3))\n", + "# [[0.10073292 0.14624784 0.40273923]\n", + "# [0.21844459 0.22226682 0.37246217]\n", + "# [0.50334257 0.01714939 0.47780388]\n", + "# [0.08755349 0.86500477 0.70566398]]\n", + "\n", + "np.random.seed(20200614)\n", + "print(np.random.uniform()) # 0.7594819171852776\n", + "print(np.random.uniform(size=5))\n", + "# [0.75165827 0.16552651 0.0538581 0.46671446 0.89076925]\n", + "\n", + "print(np.random.uniform(size=(4, 3)))\n", + "# [[0.10073292 0.14624784 0.40273923]\n", + "# [0.21844459 0.22226682 0.37246217]\n", + "# [0.50334257 0.01714939 0.47780388]\n", + "# [0.08755349 0.86500477 0.70566398]]\n", + "```\n", + "\n", + "作为`uniform`的另一特例,可以得到`[low,high)`之间均匀分布的随机整数。\n", + "\n", + "- `numpy.random.randint(low, high=None, size=None, dtype='l')` Return random integers from `low` (inclusive) to `high` (exclusive).\n", + "\n", + "Return random integers from the “discrete uniform” distribution of the specified dtype in the “half-open” interval [low, high). If high is None (the default), then results are from [0, low).\n", + "\n", + "\n", + "【例】若`high`不为`None`时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数。\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200614)\n", + "x = np.random.randint(2, size=10)\n", + "print(x)\n", + "# [0 0 0 1 0 1 0 0 0 0]\n", + "\n", + "x = np.random.randint(1, size=10)\n", + "print(x)\n", + "# [0 0 0 0 0 0 0 0 0 0]\n", + "\n", + "x = np.random.randint(5, size=(2, 4))\n", + "print(x)\n", + "# [[3 3 0 1]\n", + "# [1 1 0 1]]\n", + "\n", + "x = np.random.randint(1, 10, [3, 4])\n", + "print(x)\n", + "# [[2 1 7 7]\n", + "# [7 2 4 6]\n", + "# [8 7 2 8]]\n", + "```\n", + "\n", + "\n", + "## 正态分布\n", + "\n", + "标准正态分布数学表示:\n", + "![task11%E9%9A%8F%E6%9C%BA%E6%8A%BD%E6%A0%B7-%E5%9D%87%E5%8C%80%E5%88%86%E5%B8%83-%E6%95%B0%E5%AD%A6%E8%A1%A8%E7%A4%BA%E5%85%AC%E5%BC%8F.png](attachment:task11%E9%9A%8F%E6%9C%BA%E6%8A%BD%E6%A0%B7-%E5%9D%87%E5%8C%80%E5%88%86%E5%B8%83-%E6%95%B0%E5%AD%A6%E8%A1%A8%E7%A4%BA%E5%85%AC%E5%BC%8F.png)\n", + "\n", + "- `numpy.random.randn(d0, d1, ..., dn)` Return a sample (or samples) from the \"standard normal\" distribution.\n", + "\n", + "\n", + "\n", + "【例】根据指定大小产生满足标准正态分布的数组(均值为0,标准差为1)。\n", + "\n", + "```python\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from scipy import stats\n", + "\n", + "np.random.seed(20200614)\n", + "size = 50000\n", + "x = np.random.randn(size)\n", + "y1 = (np.sum(x < 1) - np.sum(x < -1)) / size\n", + "y2 = (np.sum(x < 2) - np.sum(x < -2)) / size\n", + "y3 = (np.sum(x < 3) - np.sum(x < -3)) / size\n", + "print(y1) # 0.68596\n", + "print(y2) # 0.95456\n", + "print(y3) # 0.99744\n", + "\n", + "plt.hist(x, bins=20)\n", + "plt.show()\n", + "\n", + "y1 = stats.norm.cdf(1) - stats.norm.cdf(-1)\n", + "y2 = stats.norm.cdf(2) - stats.norm.cdf(-2)\n", + "y3 = stats.norm.cdf(3) - stats.norm.cdf(-3)\n", + "print(y1) # 0.6826894921370859\n", + "print(y2) # 0.9544997361036416\n", + "print(y3) # 0.9973002039367398\n", + "```\n", + "\n", + "![](https://img-blog.csdnimg.cn/20200614200342168.png)\n", + "\n", + "\n", + "还可以指定分布以及所需参数来进行随机,例如高斯分布中的mu和sigma。\n", + "\n", + "- `numpy.random.normal(loc=0.0, scale=1.0, size=None)` Draw random samples from a normal (Gaussian) distribution.\n", + "\n", + "`normal()`为创建均值为 loc(mu),标准差为 scale(sigma),大小为 size 的数组。\n", + "![task11%E9%9A%8F%E6%9C%BA%E6%8A%BD%E6%A0%B7-%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83-%E5%85%AC%E5%BC%8F%E5%B0%8F.jpg](attachment:task11%E9%9A%8F%E6%9C%BA%E6%8A%BD%E6%A0%B7-%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83-%E5%85%AC%E5%BC%8F%E5%B0%8F.jpg)\n", + "\n", + "```python\n", + "sigma * np.random.randn(...) + mu\n", + "```\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "np.random.seed(20200614)\n", + "x = 0.5 * np.random.randn(2, 4) + 5\n", + "'''或者\n", + "#模拟10000个随机变量\n", + "x = 0.5*stats.norm.rvs(size=(2,4))+5\n", + "'''\n", + "print(x)\n", + "# [[5.39654234 5.4088702 5.49104652 4.95817289]\n", + "# [4.31977933 4.76502391 4.70720327 4.36239023]]\n", + "\n", + "np.random.seed(20200614)\n", + "mu = 5#平均值\n", + "sigma = 0.5#标准差\n", + "x = np.random.normal(mu, sigma, (2, 4))\n", + "print(x)\n", + "# [[5.39654234 5.4088702 5.49104652 4.95817289]\n", + "# [4.31977933 4.76502391 4.70720327 4.36239023]]\n", + "\n", + "size = 50000\n", + "x = np.random.normal(mu, sigma, size)\n", + "\n", + "print(np.mean(x)) # 4.996403463175092\n", + "print(np.std(x, ddof=1)) # 0.4986846716715106(#样本标准差)\n", + "'''\n", + "ddof:int, optional\n", + "Means Delta Degrees of Freedom. The divisor used in calculations is N - ddof, where N represents the number of elements. By default ddof is zero.\n", + "'''\n", + "```\n", + "![task11%E9%9A%8F%E6%9C%BA%E6%8A%BD%E6%A0%B7-%E6%A0%B7%E6%9C%AC%E6%A0%87%E5%87%86%E5%B7%AE.png](attachment:task11%E9%9A%8F%E6%9C%BA%E6%8A%BD%E6%A0%B7-%E6%A0%B7%E6%9C%AC%E6%A0%87%E5%87%86%E5%B7%AE.png)\n", + "```\n", + "plt.hist(x, bins=20)\n", + "plt.show()\n", + "```\n", + "\n", + "![](https://img-blog.csdnimg.cn/20200614204430538.png)\n", + "\n", + "## 指数分布\n", + "指数分布描述时间发生的时间长度间隔。\n", + "\n", + "指数分布的数学表示:![task11%E9%9A%8F%E6%9C%BA%E6%8A%BD%E6%A0%B7-%E6%8C%87%E6%95%B0%E5%88%86%E5%B8%83-%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F.png](attachment:task11%E9%9A%8F%E6%9C%BA%E6%8A%BD%E6%A0%B7-%E6%8C%87%E6%95%B0%E5%88%86%E5%B8%83-%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F.png)\n", + "\n", + "- `numpy.random.exponential(scale=1.0, size=None)` Draw samples from an exponential distribution.\n", + "\n", + "【例】`scale = 1/lambda`\n", + "```python\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from scipy import stats\n", + "\n", + "np.random.seed(20200614)\n", + "lam = 7\n", + "size = 50000\n", + "x = np.random.exponential(1 / lam, size)\n", + "'''或者\n", + "#rvs(loc=0, scale=1/lam, size=size, random_state=None)模拟\n", + "'''\n", + "y1 = (np.sum(x < 1 / 7)) / size\n", + "y2 = (np.sum(x < 2 / 7)) / size\n", + "y3 = (np.sum(x < 3 / 7)) / size\n", + "print(y1) # 0.63218\n", + "print(y2) # 0.86518\n", + "print(y3) # 0.95056\n", + "\n", + "plt.hist(x, bins=20)\n", + "plt.show()\n", + "\n", + "y1 = stats.expon.cdf(1 / 7, scale=1 / lam)\n", + "y2 = stats.expon.cdf(2 / 7, scale=1 / lam)\n", + "y3 = stats.expon.cdf(3 / 7, scale=1 / lam)\n", + "print(y1) # 0.6321205588285577\n", + "print(y2) # 0.8646647167633873\n", + "print(y3) # 0.950212931632136\n", + "```\n", + "\n", + "![](https://img-blog.csdnimg.cn/20200614211345205.png)\n", + "\n", + "\n", + "---\n", + "# 其它随机函数\n", + "\n", + "## 随机从序列中获取元素\n", + "- `numpy.random.choice(a, size=None, replace=True, p=None)` Generates a random sample from a given 1-D array.\n", + "\n", + "从序列中获取元素,若`a`为整数,元素取值从`np.range(a)`中随机获取;若`a`为数组,取值从`a`数组元素中随机获取。该函数还可以控制生成数组中的元素是否重复`replace`,以及选取元素的概率`p`。\n", + "\n", + "【例】\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200614)\n", + "x = np.random.choice(10, 3)\n", + "print(x) # [2 0 1]\n", + "\n", + "x = np.random.choice(10, 3, p=[0.05, 0, 0.05, 0.9, 0, 0, 0, 0, 0, 0])\n", + "print(x) # [3 2 3]\n", + "\n", + "x = np.random.choice(10, 3, replace=False, p=[0.05, 0, 0.05, 0.9, 0, 0, 0, 0, 0, 0])\n", + "print(x) # [3 0 2]\n", + "\n", + "aa_milne_arr = ['pooh', 'rabbit', 'piglet', 'Christopher']\n", + "x = np.random.choice(aa_milne_arr, 5, p=[0.5, 0.1, 0.1, 0.3])\n", + "print(x) # ['pooh' 'rabbit' 'pooh' 'pooh' 'pooh']\n", + "\n", + "np.random.seed(20200614)\n", + "x = np.random.randint(0, 10, 3)\n", + "print(x) # [2 0 1]\n", + "```\n", + "## 对数据集进行洗牌操作\n", + "\n", + "数据一般都是按照采集顺序排列的,但是在机器学习中很多算法都要求数据之间相互独立,所以需要先对数据集进行洗牌操作。\n", + "\n", + "- `numpy.random.shuffle(x)` Modify a sequence in-place by shuffling its contents.\n", + "\n", + "This function only shuffles the array along the first axis of a multi-dimensional array. The order of sub-arrays is changed but their contents remains the same.\n", + "\n", + "对`x`进行重排序,如果`x`为多维数组,只沿第 0 轴洗牌,改变原来的数组,输出为None。\n", + "\n", + "【例】洗牌,改变自身内容,打乱顺序。\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200614)\n", + "x = np.arange(10)\n", + "np.random.shuffle(x)\n", + "print(x)\n", + "# [6 8 7 5 3 9 1 4 0 2]\n", + "\n", + "print(np.random.shuffle([1, 4, 9, 12, 15]))\n", + "# None\n", + "\n", + "x = np.arange(20).reshape((5, 4))\n", + "print(x)\n", + "# [[ 0 1 2 3]\n", + "# [ 4 5 6 7]\n", + "# [ 8 9 10 11]\n", + "# [12 13 14 15]\n", + "# [16 17 18 19]]\n", + "\n", + "np.random.shuffle(x)\n", + "print(x)\n", + "# [[ 4 5 6 7]\n", + "# [ 0 1 2 3]\n", + "# [ 8 9 10 11]\n", + "# [16 17 18 19]\n", + "# [12 13 14 15]]\n", + "```\n", + "\n", + "- `numpy.random.permutation(x)` Randomly permute a sequence, or return a permuted range.\n", + "\n", + "If `x` is a multi-dimensional array, it is only shuffled along its first index.\n", + " \n", + "`permutation()`函数的作用与`shuffle()`函数相同,可以打乱第0轴的数据,但是它不会改变原来的数组。\n", + "\n", + "【例】\n", + "\n", + "```python\n", + "import numpy as np\n", + "\n", + "np.random.seed(20200614)\n", + "x = np.arange(10)\n", + "y = np.random.permutation(x)\n", + "print(y)\n", + "# [6 8 7 5 3 9 1 4 0 2]\n", + "\n", + "print(np.random.permutation([1, 4, 9, 12, 15]))\n", + "# [ 4 1 9 15 12]\n", + "\n", + "x = np.arange(20).reshape((5, 4))\n", + "print(x)\n", + "# [[ 0 1 2 3]\n", + "# [ 4 5 6 7]\n", + "# [ 8 9 10 11]\n", + "# [12 13 14 15]\n", + "# [16 17 18 19]]\n", + "\n", + "y = np.random.permutation(x)\n", + "print(y)\n", + "# [[ 8 9 10 11]\n", + "# [ 0 1 2 3]\n", + "# [12 13 14 15]\n", + "# [16 17 18 19]\n", + "# [ 4 5 6 7]]\n", + "```\n", + "\n", + "\n", + "\n", + "\n", + "---\n", + "**参考文献**\n", + "- https://www.jianshu.com/p/63434ad5ea64\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T01:02:02.029113Z", + "start_time": "2020-09-15T01:02:02.026084Z" + } + }, + "outputs": [], + "source": [ + "dic={1:('I','V'),2:('X','L'),3:('C','D'),4:'M'}" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T01:02:09.390007Z", + "start_time": "2020-09-15T01:02:09.379035Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'M'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dic[4]" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-15T01:02:29.206128Z", + "start_time": "2020-09-15T01:02:29.201134Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'I'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python35", + "language": "python", + "name": "python35" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "165px" + }, + "toc_section_display": true, + "toc_window_display": true + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}