{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A69AC7A8D039456492A58F4670474397",
    "jupyter": {},
    "mdEditEnable": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "Numpy是Python做数据分析所必须要掌握的基础库之一。\n",
    "\n",
    "\n",
    "---\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "D3EA769E89C04B1C98D7EEC27B000CF7",
    "jupyter": {},
    "mdEditEnable": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 1. 导入```numpy```库并简写为 `np` (★☆☆) \n",
    "(**提示**: ```import … as …```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true,
    "id": "9D78D931517E432FA973C0DFF57BC78B",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "20AFD585027B441186903FB6F16CAA77",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 2. 打印```numpy```的版本和配置说明 (★☆☆) \n",
    "(**提示**: ```np.__version__, np.show_config```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true,
    "id": "D705477270FF47D69C42E337B57DFC10",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(np.__version__)\n",
    "# np.show_config()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "1E6BD3752DEF4E698704E50AA0EBE92C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 3. 创建一个长度为10的空向量 (★☆☆) \n",
    "(**提示**: ```np.zeros```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true,
    "id": "41292630A6F64C3391CF4AC90606EB62",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.zeros(10)\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "C8C4597CD9F1403BAD09C3601BFB771B",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 4.  如何找到任何一个数组的内存大小？ (★☆☆)\n",
    "(**提示**: ```size, itemsize```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true,
    "id": "42640A317E3544118E6C4E76DED8525C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.zeros((10,10))\n",
    "# print(\"%d bytes\" % (Z.size * Z.itemsize))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "04C04BB115BD4AF687192E229581A9C1",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 5. 如何从命令行得到```numpy```中```add```函数的说明文档? (★☆☆) \n",
    "(**提示**: ```np.info```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true,
    "id": "9138EB4B567942018EF386A8DB116F60",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# numpy.info(numpy.add)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "7BEAD42C1F124A88851E1D4766DC2FDC",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 6. 创建一个长度为10并且除了第五个值为1的空向量 (★☆☆) \n",
    "(**提示**: ```array[4]```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true,
    "id": "C28FC474E3124C97AA0E95DE2AE6DDED",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.zeros(10)\n",
    "# Z[4] = 1\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "CA86859BD5FE44888383B564D3281A88",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 7.  创建一个值域范围从10到49的向量(★☆☆) \n",
    "(**提示**: ```np.arange```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true,
    "id": "3C0F52C0DD8B42C0908DA28387686BF5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(10,50)\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8E233C2183494F5185095C23FD390953",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 8.  反转一个向量(第一个元素变为最后一个) (★☆☆) \n",
    "(**提示**: ```array[::-1]```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true,
    "id": "AE86CCAF12044CED8445E5476F0EC695",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(50)\n",
    "# Z = Z[::-1]\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "9ABF19E9BDDF41E6BDD0EC15890B452B",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 9.  创建一个 ```3x3``` 并且值从0到8的矩阵(★☆☆) \n",
    "(**提示**: ```reshape```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true,
    "id": "FE30B2979C01496681E90910A011A276",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(9).reshape(3,3)\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8FF7AF19C2344E37BFDE905F618E47E9",
    "jupyter": {},
    "mdEditEnable": false,
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 10. 找到数组```[1,2,0,0,4,0]```中非0元素的位置索引 (★☆☆) \n",
    "(**提示**: ```np.nonzero```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true,
    "id": "CF6B96A0E8FA4FB588249E6E6DB89657",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# nz = np.nonzero([1,2,0,0,4,0])\n",
    "# print(nz)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "B431E1E8247640A58BDAACA967F5E104",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 11. 创建一个 ```3x3``` 的单位矩阵 (★☆☆) \n",
    "(**提示**: ```np.eye```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true,
    "id": "B09137867EFA48C4AA58DBCB0F3AE455",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.eye(3)\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8C4D8FCF233D43B28DC51B81879D4EA3",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 12. 创建一个 ```3x3x3```的随机数组 (★☆☆) \n",
    "(**提示**: ```np.random.random```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true,
    "id": "7B99B6FBF2594BF7862AC75134813F8C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.random((3,3,3))\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "F566B47F9E574BE1876B8AF746BB1410",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 13. 创建一个 ```10x10``` 的随机数组并找到它的最大值和最小值 (★☆☆) \n",
    "(**提示**: ```min, max```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true,
    "id": "69474CA4E1B144DB9DFEC144DED5EA34",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.random((10,10))\n",
    "# Zmin, Zmax = Z.min(), Z.max()\n",
    "# print(Zmin, Zmax)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "1C91060ECCFD4CCB8DC6849C4DA5F6B1",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 14. 创建一个长度为30的随机向量并找到它的平均值 (★☆☆) \n",
    "(**提示**: ```mean```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true,
    "id": "4CC6FD8D2EE94C5CB9C016F753FECA6F",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.random(30)\n",
    "# m = Z.mean()\n",
    "# print(m)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3BB48A32125C46FF8595C4BD8496BDF2",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 15. 创建一个二维数组，其中边界值为1，其余值为0 (★☆☆) \n",
    "(**提示**: ```array[1:-1, 1:-1]```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true,
    "id": "DD81EF89D40347959726C00E6D4960FB",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.ones((10,10))\n",
    "# Z[1:-1,1:-1] = 0\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3E757B4834EC47038E1BE151D9216D24",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 16. 对于一个存在在数组，如何添加一个用0填充的边界? (★☆☆) \n",
    "(**提示**: ```np.pad```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true,
    "id": "50C827FEF7494D648C5851A1892D781E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.ones((5,5))\n",
    "# Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0)\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "91F10E5D65C245C28315A74D340DE25E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 17. 以下表达式运行的结果分别是什么? (★☆☆) \n",
    "(**提示**: ```NaN = not a number, inf = infinity```)\n",
    "```python\n",
    "0 * np.nan\n",
    "np.nan == np.nan\n",
    "np.inf > np.nan\n",
    "np.nan - np.nan\n",
    "0.3 == 3 * 0.1\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true,
    "id": "5099C44330384C148B6C75BB8F8B0C1C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(0 * np.nan)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true,
    "id": "6B26448558014F8E811F947E38EA0CC3",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(np.nan == np.nan)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true,
    "id": "2250DCFDAF35421782B8468BAD931692",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(np.inf > np.nan)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true,
    "id": "FDB7272792FA413FB8E610D62DE2645F",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(np.nan - np.nan)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true,
    "id": "B991F0C2294442B38127DA786ACFAA8E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(0.3 == 3 * 0.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4019417908674DE49895DAF9E9806F2E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 18. 创建一个 ```5x5```的矩阵，并设置值1,2,3,4落在其对角线下方位置 (★☆☆) \n",
    "(**提示**: ```np.diag```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true,
    "id": "712527DF95664A3A8C6568BB2A5D08C6",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.diag(1+np.arange(4),k=-1)\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4B0E4200FE8A48D1852A71D9120E6003",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 19. 创建一个``` 8x8``` 的矩阵，并且设置成棋盘样式 (★☆☆) \n",
    "(**提示**: ```array[::2]```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": true,
    "id": "2C5E5A07FD84446780749AC3E09D72F6",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.zeros((8,8),dtype=int)\n",
    "# Z[1::2,::2] = 1\n",
    "# Z[::2,1::2] = 1\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "C161AAFC72C74F98999DA7C3326DFC07",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 20. 考虑一个 (6,7,8) 形状的数组，其第100个元素的索引(x,y,z)是什么? \n",
    "(**提示**: ```np.unravel_index```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": true,
    "id": "35A916EDE9F34778949694347D7EED5F",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(np.unravel_index(100,(6,7,8)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "DBC41AC1D41E43F98B4D0A270F1E6987",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 21. 用```tile```函数去创建一个 ```8x8```的棋盘样式矩阵(★☆☆) \n",
    "(**提示**: ```np.tile```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true,
    "id": "44FFB3BC499C4CE3AFD4B81B2EBADD1E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.tile( np.array([[0,1],[1,0]]), (4,4))\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "92086F95E7ED4E8091C40BECE2606018",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 22. 对一个```5x5```的随机矩阵做归一化(★☆☆) \n",
    "(**提示**: ```(x - min) / (max - min)```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": true,
    "id": "44305FE5FF3545C1B4E80254CE276D30",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "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": {
    "id": "31DDD5EC850B456C8ED766880CB032B1",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 23. 创建一个将颜色描述为(RGBA)四个无符号字节的自定义```dtype```？(★☆☆) \n",
    "(**提示**: ```np.dtype```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": true,
    "id": "F5033802C2EC41768FA02565B2116391",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# color = np.dtype([(\"r\", np.ubyte, 1),\n",
    "#                   (\"g\", np.ubyte, 1),\n",
    "#                   (\"b\", np.ubyte, 1),\n",
    "#                   (\"a\", np.ubyte, 1)])\n",
    "# color"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "90D1829F563F4B338D9C333B0A5E6F06",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 24. 一个```5x3```的矩阵与一个```3x2```的矩阵相乘，实矩阵乘积是什么？ (★☆☆) \n",
    "(**提示**: ```np.dot | @```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true,
    "id": "E5F4646106CD449DB590BE25CD6FBF27",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.dot(np.ones((5,3)), np.ones((3,2)))\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2BC071A5CE5448D28C1A9FDEE2D02F4E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 25. 给定一个一维数组，对其在3到8之间的所有元素取反 (★☆☆) \n",
    "(**提示**: ```>, <=```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": true,
    "id": "23E937FDBAE043FAB0192B316A6D6F3E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(11)\n",
    "# Z[(3 < Z) & (Z <= 8)] *= -1\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A72EC713523C4CEF97ADA412621678D5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 26. 下面脚本运行后的结果是什么? (★☆☆) \n",
    "(**提示**: np.sum)\n",
    "```python\n",
    "print(sum(range(5),-1))\n",
    "from numpy import *\n",
    "print(sum(range(5),-1))\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": true,
    "id": "519A129944AC4CF58C6985F559BC3881",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(sum(range(5),-1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": true,
    "id": "EDD3AF4393074CF98A5B2754552443BE",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# from numpy import *\n",
    "# print(sum(range(5),-1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "42932F8259944D7E80D5C79D8B38A320",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 27. 考虑一个整数向量Z,下列表达合法的是哪个? (★☆☆)\n",
    "```python\n",
    "Z**Z\n",
    "2 << Z >> 2\n",
    "Z <- Z\n",
    "1j*Z\n",
    "Z/1/1\n",
    "Z<Z>Z\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": true,
    "id": "E99C3DCEB8FB4200AA60D4DCF22EB2A8",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(5)\n",
    "# Z ** Z  # legal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": true,
    "id": "D81A330CCEA2479E8E781EA468D3C68A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(5)\n",
    "# 2 << Z >> 2  # false"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": true,
    "id": "E1E168B997BE48ED8ED1AA507D5BC20C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(5)\n",
    "# Z <- Z   # legal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true,
    "id": "A72D8CF7DBA14202830DDE74AC0FDFAF",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(5)\n",
    "# 1j*Z   # legal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": true,
    "id": "BB7023C33FA6455C89362695EACC78F4",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(5)\n",
    "# Z/1/1   # legal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": true,
    "id": "90BF25CACF044F6F8937CC226A1E781A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(5)\n",
    "# Z<Z>Z    # false"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "AFDD8E04D3C2492CA81547489A2FB3FD",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 28. 下列表达式的结果分别是什么?(★☆☆) \n",
    "```python\n",
    "np.array(0) / np.array(0)\n",
    "np.array(0) // np.array(0)\n",
    "np.array([np.nan]).astype(int).astype(float)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": true,
    "id": "A719B41935824F908DFE6CD47FF24B9F",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(np.array(0) / np.array(0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": true,
    "id": "E4EE66660AF2480B9C83C147878295E5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(np.array(0) // np.array(0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": true,
    "id": "B42B92AB0C6D4F948AF26CBE383CCC67",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print(np.array([np.nan]).astype(int).astype(float))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "D021C8ACC0D940DA994E073486BE2C9C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 29. 如何从零位对浮点数组做舍入 ? (★☆☆) \n",
    "(**提示**: ```np.uniform, np.copysign, np.ceil, np.abs```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": true,
    "id": "D9EE837214154F149529C76396C2EE79",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.uniform(-10,+10,10)\n",
    "# print (np.copysign(np.ceil(np.abs(Z)), Z))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "06D7AFD7163D49BC8C20348EA26C54C9",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 30. 如何找到两个数组中的共同元素? (★☆☆) \n",
    "(**提示**: ```np.intersect1d```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": true,
    "id": "D2A344B9FCC94DDCBB82EC94CE3DD668",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z1 = np.random.randint(0,10,10)\n",
    "# Z2 = np.random.randint(0,10,10)\n",
    "# print(np.intersect1d(Z1,Z2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "1573CCEE2F754648879030F4866898B9",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 31. 如何忽略所有的 ```numpy``` 警告(尽管不建议这么做)? (★☆☆) \n",
    "(**提示**: ```np.seterr, np.errstate```)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "9D273F962459416BB206C0F93F2F8D08",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "```python\n",
    "# Suicide mode on\n",
    "defaults = np.seterr(all=\"ignore\")\n",
    "Z = np.ones(1) / 0\n",
    "\n",
    "# Back to sanity\n",
    "_ = np.seterr(**defaults)\n",
    "\n",
    "An equivalent way, with a context manager:\n",
    "\n",
    "with np.errstate(divide='ignore'):\n",
    "    Z = np.ones(1) / 0\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "C513CAD2620F417FAD6D8859C3AF1883",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 32. 下面的表达式是正确的吗? (★☆☆) \n",
    "(**提示**: imaginary number)\n",
    "```python\n",
    "np.sqrt(-1) == np.emath.sqrt(-1)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": true,
    "id": "7B70B61A32D04CF68CDD1D44A0C2C19B",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# np.sqrt(-1) == np.emath.sqrt(-1)  # False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A45D7F283E0B456E81829DDEF2E13FE5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 33. 如何得到昨天，今天，明天的日期? (★☆☆) \n",
    "(**提示**: ```np.datetime64, np.timedelta64```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": true,
    "id": "031F2BA107374ED6837FCAC6F96884E5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "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')\n",
    "# print (\"Yesterday is \" + str(yesterday))\n",
    "# print (\"Today is \" + str(today))\n",
    "# print (\"Tomorrow is \"+ str(tomorrow))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "9DDDA7EE921A4674B754BB8E40F1CCAE",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 34. 如何得到所有与2016年7月对应的日期？ (★★☆) \n",
    "(**提示**: ```np.arange(dtype=datetime64['D'])```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "collapsed": true,
    "id": "B937D12F01784CFE84E214718F9A3CBC",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange('2016-07', '2016-08', dtype='datetime64[D]')\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "AAC83583B8EC400687E5505ECAE0E435",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 35. 如何直接在位计算```(A+B)\\*(-A/2)```(不建立副本)? (★★☆) \n",
    "(**提示**: ```np.add(out=), np.negative(out=), np.multiply(out=), np.divide(out=)```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": true,
    "id": "E686188C9965478DBCA16C3FF4853052",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# A = np.ones(3)*1\n",
    "# B = np.ones(3)*2\n",
    "# C = np.ones(3)*3\n",
    "# np.add(A,B,out=B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": true,
    "id": "AA936812BA394FA187A4B3B17581AB23",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# np.divide(A,2,out=A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": true,
    "id": "929DE1B8AA494C76B855CC88ACBAAF48",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# np.negative(A,out=A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": true,
    "id": "FDA87EC072CD4B9A907321B926C41407",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# np.multiply(A,B,out=A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "502537DCE0AA46E387883CF90133D718",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 36. 用五种不同的方法去提取一个随机数组的整数部分(★★☆) \n",
    "(**提示**: ```%, np.floor, np.ceil, astype, np.trunc```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "collapsed": true,
    "id": "A58464DF10D34B8A8BFA134D44C9CF56",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.uniform(0,10,10)\n",
    "\n",
    "# print (Z - Z%1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "collapsed": true,
    "id": "6B2201271C154961B7928E1EFF540CBB",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print (np.floor(Z))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": true,
    "id": "58363BA8D19D4BC2A578159905B71B46",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print (np.ceil(Z)-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "collapsed": true,
    "id": "6745FA7466464D18BE4FDBAC96EEA98D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print (Z.astype(int))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "collapsed": true,
    "id": "5543995A0FD14D378AD7CA4F84D621E6",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print (np.trunc(Z))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "E9BC7D19D7214712BEBECE1FBA90C5B4",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 37. 创建一个```5x5```的矩阵，其中每行的数值范围从0到4 (★★☆) \n",
    "(**提示**: ```np.arange```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "collapsed": true,
    "id": "F046ACCD114749428AD0A7AD10DF76E8",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.zeros((5,5))\n",
    "# Z += np.arange(5)\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "011C9D30472C49438273D09B10DE1257",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 38. 通过考虑一个可生成10个整数的函数，来构建一个数组(★☆☆) \n",
    "(**提示**: ```np.fromiter```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "collapsed": true,
    "id": "B19FAA5F434E4770B56B36D8EACEF3ED",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# def generate():\n",
    "#     for x in range(10):\n",
    "#         yield x\n",
    "# Z = np.fromiter(generate(),dtype=float,count=-1)\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "29274F560F6244E2832804107CD1BDD5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 39. 创建一个长度为10的随机向量，其值域范围从0到1，但是不包括0和1 (★★☆) \n",
    "(**提示**: ```np.linspace```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "collapsed": true,
    "id": "EE10F710B4F844FC81A16EF7777F229B",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.linspace(0,1,11,endpoint=False)[1:]\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "F8583210BCF048B9B313B36BEEC4DE67",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 40. 创建一个长度为10的随机向量，并将其排序 (★★☆) \n",
    "(**提示**: ```sort```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": true,
    "id": "CBFC87DACC404D6289933C746DFC0735",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.random(10)\n",
    "# Z.sort()\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "C19BB964416F4F7586F1996ABC00373E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 41.对于一个小数组，如何用比 ```np.sum```更快的方式对其求和？(★★☆) \n",
    "(**提示**: ```np.add.reduce```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": true,
    "id": "47573260DA734DA7A9C654D6DC754C49",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(10)\n",
    "# np.add.reduce(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0AA3A2F5B19F47A19318A13D5888FC99",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 42. 对于两个随机数组A和B，检查它们是否相等(★★☆) \n",
    "(**提示**: ```np.allclose, np.array_equal```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": true,
    "id": "1448EB4CCEF54A9BB5C6CDECCBC556B5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# A = np.random.randint(0,2,5)\n",
    "# B = np.random.randint(0,2,5)\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": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": true,
    "id": "A9479E221501459597EA782EA19CB7C2",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # 方法2\n",
    "# # Checking both the shape and the element values, no tolerance (values have to be exactly equal)\n",
    "# equal = np.array_equal(A,B)\n",
    "# print(equal)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "19B0C351B16F4FE6A88CAA9F8845EA8A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 43. 创建一个只读数组(read-only) (★★☆) \n",
    "(**提示**: ```flags.writeable```)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "B7E6E1870CAB44BC8209B4C5501FE767",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "```python\n",
    "# 使用如下过程实现\n",
    "Z = np.zeros(10)\n",
    "Z.flags.writeable = False\n",
    "Z[0] = 1\n",
    "---------------------------------------------------------------------------\n",
    "ValueError                                Traceback (most recent call last)\n",
    "<ipython-input-54-6fd4c6570dd1> in <module>()\n",
    "      1 Z = np.zeros(10)\n",
    "      2 Z.flags.writeable = False\n",
    "----> 3 Z[0] = 1\n",
    "\n",
    "ValueError: assignment destination is read-only\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "98DFC2521652463589FF8DDAF36B08FE",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 44. 将笛卡尔坐标下的一个```10x2```的矩阵转换为极坐标形式(★★☆) \n",
    "(**hint**: ```np.sqrt, np.arctan2```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "collapsed": true,
    "id": "CF88855CE1504CC1BC1C867605DA8BB7",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.random((10,2))\n",
    "# X,Y = Z[:,0], Z[:,1]\n",
    "# R = np.sqrt(X**2+Y**2)\n",
    "# T = np.arctan2(Y,X)\n",
    "# print (R)\n",
    "# print (T)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "D07B13CEE9B24B9B88165ADF6CBA7401",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 45. 创建一个长度为10的向量，并将向量中最大值替换为1 (★★☆) \n",
    "(**提示**: ```argmax```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "collapsed": true,
    "id": "3AE6B7B7914149238A6A28CD0A8DAA9E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.random(10)\n",
    "# Z[Z.argmax()] = 0\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0F820B0DF2E14655890CD971AE0272D3",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 46. 创建一个结构化数组，并实现 `x` 和 `y` 坐标覆盖 ```[0,1]x[0,1]``` 区域 (★★☆) \n",
    "(**提示**: ```np.meshgrid```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "collapsed": true,
    "id": "7BD9ED6C246544858EB94CB9F785A150",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.zeros((5,5), [('x',float),('y',float)])\n",
    "# Z['x'], Z['y'] = np.meshgrid(np.linspace(0,1,5),\n",
    "#                              np.linspace(0,1,5))\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "73EEF9858D8E4A828272CCC7BCE20A43",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "####  47. 给定两个数组```X```和```Y```，构造Cauchy矩阵C ```(Cij =1/(xi - yj))```\n",
    "(**提示**: ```np.subtract.outer```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "collapsed": true,
    "id": "C9BCA7FFCB8544838CE8DD8524844817",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# X = np.arange(8)\n",
    "# Y = X + 0.5\n",
    "# C = 1.0 / np.subtract.outer(X, Y)\n",
    "# print(np.linalg.det(C))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "FC59A059DD094F4BB5CDC4E229958AED",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 48. 打印每个numpy标量类型的最小值和最大值？ (★★☆) \n",
    "(**提示**: ```np.iinfo, np.finfo, eps```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": true,
    "id": "F4575981070D41FA8983FB07431CB87A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# for dtype in [np.int8, np.int32, np.int64]:\n",
    "#     print(np.iinfo(dtype).min)\n",
    "#     print(np.iinfo(dtype).max)\n",
    "\n",
    "# for dtype in [np.float32, np.float64]:\n",
    "#     print(np.finfo(dtype).min)\n",
    "#     print(np.finfo(dtype).max)\n",
    "#     print(np.finfo(dtype).eps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "DF957A2129FB4636A8F47A765DF0F96F",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 49. 如何打印一个数组中的所有数值? (★★☆) \n",
    "(**提示**: ```np.set_printoptions```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": true,
    "id": "56EA8BE07DE04A0D847D4FC7FD545A76",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# np.set_printoptions(threshold=np.nan)\n",
    "# Z = np.zeros((16,16))\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4CDD8B8C9AB94302813674249668C14C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 50. 给定标量时，如何找到数组中最接近标量的值？(★★☆) \n",
    "(**提示**: ```argmin```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "collapsed": true,
    "id": "04BC778A88C14ABF83B1C9B99F9D32BF",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(100)\n",
    "# v = np.random.uniform(0,100)\n",
    "# index = (np.abs(Z-v)).argmin()\n",
    "# print (Z[index])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "B8BDE1CC85E749D4B1F5AAFDC6969810",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 51. 创建一个表示位置```(x,y)```和颜色```(r,g,b)```的结构化数组(★★☆) \n",
    "(**提示**: ```dtype```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "collapsed": true,
    "id": "46DA786D707840318F1B9FDFE16644C1",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.zeros(10, [ ('position', [ ('x', float, 1),\n",
    "#                                   ('y', float, 1)]),\n",
    "#                    ('color',    [ ('r', float, 1),\n",
    "#                                   ('g', float, 1),\n",
    "#                                   ('b', float, 1)])])\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "DC2A897ACBBE4659BF4490F0BD2A35C3",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 52. 对一个表示坐标形状为(100,2)的随机向量，找到点与点的距离(★★☆) \n",
    "(**提示**: ```np.atleast_2d, T, np.sqrt)```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "collapsed": true,
    "id": "0595F131624F49E6859D0BA252FEA44D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.random((10,2))\n",
    "# X,Y = np.atleast_2d(Z[:,0], Z[:,1])\n",
    "# D = np.sqrt( (X-X.T)**2 + (Y-Y.T)**2)\n",
    "# print (D)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "collapsed": true,
    "id": "AF5E882D646C46148A8E8FF0AA90A0B7",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # 方法2\n",
    "# # Much faster with scipy\n",
    "# import scipy\n",
    "# # Thanks Gavin Heverly-Coulson (#issue 1)\n",
    "# import scipy.spatial\n",
    "# D = scipy.spatial.distance.cdist(Z,Z)\n",
    "# print (D)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "6E021C635941407CB99EF6A4460868D8",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 53. 如何将32位的浮点数(```float```)转换为对应的整数(```integer```)?\n",
    "(**提示**: ```astype(copy=False)```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "collapsed": true,
    "id": "F3A776074F42411588D1B8840BD6CE57",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(10, dtype=np.int32)\n",
    "# Z = Z.astype(np.float32, copy=False)\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A89E8C46EA4C4E0C8C27BEB4B808A7F9",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 54. 如何读取以下文件? (★★☆) \n",
    "(**提示**: ```np.genfromtxt```)\n",
    "```\n",
    "1, 2, 3, 4, 5\n",
    "6,  ,  , 7, 8\n",
    " ,  , 9,10,11\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "00C8C0828A6B4DE2A052A818919776B2",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "[参考链接](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.genfromtxt.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3662D893F84D4B858513A1F791715312",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 55. 对于```numpy```数组，```enumerate```的等价操作是什么？(★★☆) \n",
    "(**提示**: ```np.ndenumerate, np.ndindex```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "collapsed": true,
    "id": "36A349A837E64D2381C729EDB4E4A1BB",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(9).reshape(3,3)\n",
    "# for index, value in np.ndenumerate(Z):\n",
    "#     print (index, value)\n",
    "# for index in np.ndindex(Z.shape):\n",
    "#     print (index, Z[index])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "1D801ED8F53849EE81F60F1A5776D82E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 56. 生成一个通用的二维Gaussian-like数组 (★★☆) \n",
    "(**提示**: ```np.meshgrid, np.exp```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "collapsed": true,
    "id": "E1271CD7CDF34116B788E66270DA72C6",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# X, Y = np.meshgrid(np.linspace(-1,1,10), np.linspace(-1,1,10))\n",
    "# D = np.sqrt(X*X+Y*Y)\n",
    "# sigma, mu = 1.0, 0.0\n",
    "# G = np.exp(-( (D-mu)**2 / ( 2.0 * sigma**2 ) ) )\n",
    "# print (G)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "5C1DE8E188344B098F39502676745D7D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 57. 对一个二维数组，如何在其内部随机放置p个元素? (★★☆) \n",
    "(**提示**: ```np.put, np.random.choice```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "collapsed": true,
    "id": "9E8F022F3F3A421480674F7EAF8C1107",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# n = 10\n",
    "# p = 3\n",
    "# Z = np.zeros((n,n))\n",
    "# np.put(Z, np.random.choice(range(n*n), p, replace=False),1)\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A42E45EE8E304C1D85385AA71201FBC4",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 58. 减去一个矩阵中的每一行的平均值 (★★☆) \n",
    "(**提示**: ```mean(axis=,keepdims=)```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "collapsed": true,
    "id": "210C23C0A0D143EE85BF270AB24F4DD4",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# X = np.random.rand(5, 10)\n",
    "# # Recent versions of numpy\n",
    "# Y = X - X.mean(axis=1, keepdims=True)\n",
    "# print(Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "collapsed": true,
    "id": "3371E9CC8B774089B2260A1C7FFDF5BE",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # 方法2\n",
    "# # Older versions of numpy\n",
    "# Y = X - X.mean(axis=1).reshape(-1, 1)\n",
    "# print (Y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "BFA3974BCF20453E8E00E5BF14BC518C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 59. 如何通过第n列对一个数组进行排序? (★★☆) \n",
    "(**提示**: ```argsort```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "collapsed": true,
    "id": "B7D468144A3A416183BB1D6B14A610B2",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.randint(0,10,(3,3))\n",
    "# print (Z)\n",
    "# print (Z[Z[:,1].argsort()])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "713E4E4CBCD44A5D83B206C137D9298A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 60. 如何检查一个二维数组是否有空列？(★★☆) \n",
    "(**提示**: ```any, ~```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "collapsed": true,
    "id": "D0E560F6FC584924887B5C25A0B9E8C5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.randint(0,3,(3,10))\n",
    "# print ((~Z.any(axis=0)).any())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "FC3FB413C733428F85D2AB6442725294",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 61. 从数组中的给定值中找出最近的值 (★★☆) \n",
    "(**提示**: ```np.abs, argmin, flat```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "collapsed": true,
    "id": "6E66FB7429FF4362800B4FB1841A32B9",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.uniform(0,1,10)\n",
    "# z = 0.5\n",
    "# m = Z.flat[np.abs(Z - z).argmin()]\n",
    "# print (m)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "02011498C99B4AF79D366C5CCCCFB38F",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 62. 如何用迭代器(```iterator```)计算两个分别具有形状(1,3)和(3,1)的数组? (★★☆) \n",
    "(**提示**: ```np.nditer```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "collapsed": true,
    "id": "85402397D0104B8A9EDC13F937E5D11B",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# A = np.arange(3).reshape(3,1)\n",
    "# B = np.arange(3).reshape(1,3)\n",
    "# it = np.nditer([A,B,None])\n",
    "# for x,y,z in it: \n",
    "#     z[...] = x + y\n",
    "# print (it.operands[2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4E73DA4B7DD9411497461196A53C90DE",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 63. 创建一个具有```name```属性的数组类(★★☆) \n",
    "(**提示**: ```class```方法)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "collapsed": true,
    "id": "A4FAF12305F14E559772A9AB42221E18",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# class NamedArray(np.ndarray):\n",
    "#     def __new__(cls, array, name=\"no name\"):\n",
    "#         obj = np.asarray(array).view(cls)\n",
    "#         obj.name = name\n",
    "#         return obj\n",
    "#     def __array_finalize__(self, obj):\n",
    "#         if obj is None: return\n",
    "#         self.info = getattr(obj, 'name', \"no name\")\n",
    "\n",
    "# Z = NamedArray(np.arange(10), \"range_10\")\n",
    "# print (Z.name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "56B6FBD96064483F83863B10A1630960",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 64. 考虑一个给定的向量，如何对由第二个向量索引的每个元素加1(小心重复的索引)? (★★★) \n",
    "(**提示**: ```np.bincount | np.add.at```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {
    "collapsed": true,
    "id": "B99FB5DF5268466F8E8EED615084EB09",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.ones(10)\n",
    "# I = np.random.randint(0,len(Z),20)\n",
    "# Z += np.bincount(I, minlength=len(Z))\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "collapsed": true,
    "id": "A7E8FD80E3A443358EF5C0E6CF945660",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # 方法2\n",
    "# np.add.at(Z, I, 1)\n",
    "# print(Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "630A718A56DF45C68AC2219FE95D19BB",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 65. 根据索引列表(```I```)，如何将向量(```X```)的元素累加到数组(```F```)? (★★★) \n",
    "(**提示**: ```np.bincount```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "collapsed": true,
    "id": "D5017E1D87B3474482F376AB7CE2DFCA",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# X = [1,2,3,4,5,6]\n",
    "# I = [1,3,9,3,4,1]\n",
    "# F = np.bincount(I,X)\n",
    "# print (F)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4A2A3596690B402E80C41EA04CD710AE",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 66. 考虑一个```(dtype=ubyte)``` 的 ```(w,h,3)```图像，计算其唯一颜色的数量(★★★) \n",
    "(**提示**: ```np.unique```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "collapsed": true,
    "id": "95A3B6B3C68A42188EB76A502A3C510F",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# w,h = 16,16\n",
    "# I = np.random.randint(0,2,(h,w,3)).astype(np.ubyte)\n",
    "# #Note that we should compute 256*256 first. \n",
    "# #Otherwise numpy will only promote F.dtype to 'uint16' and overfolw will occur\n",
    "# F = I[...,0]*(256*256) + I[...,1]*256 +I[...,2]\n",
    "# n = len(np.unique(F))\n",
    "# print (n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "FEF1B9D441DC416B868659E8ABB02D98",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 67. 考虑一个四维数组，如何一次性计算出最后两个轴(```axis```)的和？ (★★★) \n",
    "(**提示**: ```sum(axis=(-2,-1))```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "collapsed": true,
    "id": "C2F3794A1772409EAD83C123C5DDFEEC",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# A = np.random.randint(0,10,(3,4,3,4))\n",
    "# # solution by passing a tuple of axes (introduced in numpy 1.7.0)\n",
    "# sum = A.sum(axis=(-2,-1))\n",
    "# print (sum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "collapsed": true,
    "id": "A7F12DAF75C240ED91C7FD7BD21EC923",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # 方法2\n",
    "# sum = A.reshape(A.shape[:-2] + (-1,)).sum(axis=-1)\n",
    "# print (sum)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "22DA1FE2380649F5897037716C3C3FDB",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 68. 考虑一个一维向量```D```，如何使用相同大小的向量```S```来计算```D```子集的均值？(★★★) \n",
    "(**提示**: ```np.bincount```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "collapsed": true,
    "id": "BEDF3326F7694F1A89F62E88C6A56A76",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# D = np.random.uniform(0,1,100)\n",
    "# S = np.random.randint(0,10,100)\n",
    "# D_sums = np.bincount(S, weights=D)\n",
    "# D_counts = np.bincount(S)\n",
    "# D_means = D_sums / D_counts\n",
    "# print (D_means)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "collapsed": true,
    "id": "4A7CB0F23BCB41E8828E483652E1A8F0",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # 方法2\n",
    "# import pandas as pd\n",
    "# print(pd.Series(D).groupby(S).mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "F53232053DF742718EF3063B7A0FD0EB",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 69. 如何获得点积 ```dot prodcut```的对角线? (★★★) \n",
    "(**提示**: ```np.diag```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "collapsed": true,
    "id": "EBBAFF692F744180A99B6E6F301A8E0D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# A = np.random.uniform(0,1,(5,5))\n",
    "# B = np.random.uniform(0,1,(5,5))\n",
    "# # slow version\n",
    "# np.diag(np.dot(A, B))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "collapsed": true,
    "id": "084693AF2B1C4F3DAC05E4D0D0343958",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "## 方法2\n",
    "# # Fast version\n",
    "# np.sum(A * B.T, axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "collapsed": true,
    "id": "1A9C15379DF9405FB6328AD66511C088",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "## 方法3\n",
    "# # Faster version\n",
    "# np.einsum(\"ij,ji->i\", A, B)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "48EE054F54744FEC9300AD56BC62C8D7",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 70. 考虑一个向量```[1,2,3,4,5]```,如何建立一个新的向量，在这个新向量中每个值之间有3个连续的零？(★★★) \n",
    "(**提示**: ```array[::4]```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "collapsed": true,
    "id": "1CBB573916834CD18073236E24383F47",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.array([1,2,3,4,5])\n",
    "# nz = 3\n",
    "# Z0 = np.zeros(len(Z) + (len(Z)-1)*(nz))\n",
    "# Z0[::nz+1] = Z\n",
    "# print (Z0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "56D0343C2EFA4AA79407D5D219AE9C34",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 71. 考虑一个维度(5,5,3)的数组，如何将其与一个(5,5)的数组相乘？(★★★) \n",
    "(**提示**: ```array[:, :, None]```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {
    "collapsed": true,
    "id": "9D21F03160F041B9A9CFDAC5BFA8283A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# A = np.ones((5,5,3))\n",
    "# B = 2*np.ones((5,5))\n",
    "# print (A * B[:,:,None])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "FF1121B68753430CB7BE9B0C30EE1D32",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 72. 如何对一个数组中任意两行做交换? (★★★) \n",
    "(**提示**: ```array[[]] = array[[]]```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "collapsed": true,
    "id": "3DB1AC9EFA7D4FB48D3E104C567AB7D3",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# A = np.arange(25).reshape(5,5)\n",
    "# A[[0,1]] = A[[1,0]]\n",
    "# print (A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2E7011A162D342FF892C94E5B2C82AF0",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 73. 考虑一个可以描述10个三角形的triplets，找到可以分割全部三角形的line segment   \n",
    "Consider a set of 10 triplets describing 10 triangles (with shared vertices), find the set of unique line segments composing all the  triangles (★★★)     \n",
    "(**提示**: ```repeat, np.roll, np.sort, view, np.unique```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "collapsed": true,
    "id": "1F68365590154613B7E8011A52625300",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# faces = np.random.randint(0,100,(10,3))\n",
    "# F = np.roll(faces.repeat(2,axis=1),-1,axis=1)\n",
    "# F = F.reshape(len(F)*3,2)\n",
    "# F = np.sort(F,axis=1)\n",
    "# G = F.view( dtype=[('p0',F.dtype),('p1',F.dtype)] )\n",
    "# G = np.unique(G)\n",
    "# print (G)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "C4A2F864E6B24BA8A70FF32ED8CEF305",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 74. 给定一个二进制的数组```C```，如何产生一个数组```A```满足```np.bincount(A)==C```(★★★) \n",
    "(**提示**: ```np.repeat```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "collapsed": true,
    "id": "C3DA4B9685B24058A7DC2E670A1CADCF",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# C = np.bincount([1,1,2,3,4,4,6])\n",
    "# A = np.repeat(np.arange(len(C)), C)\n",
    "# print (A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "B12FD13D314349848DCC7E6C8D86DF0F",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 75. 如何通过滑动窗口计算一个数组的平均数? (★★★) \n",
    "(**提示**: ```np.cumsum```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {
    "collapsed": true,
    "id": "BE7A3F46F37B43C9BE869FB5E1AE7C8D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# def moving_average(a, n=3) :\n",
    "#     ret = np.cumsum(a, dtype=float)\n",
    "#     ret[n:] = ret[n:] - ret[:-n]\n",
    "#     return ret[n - 1:] / n\n",
    "# Z = np.arange(20)\n",
    "\n",
    "# print(moving_average(Z, n=3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "AFB78198A1D4414E8632CB88C305AD8A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 76. Consider a one-dimensional array Z, build a two-dimensional array whose first row is (Z\\[0\\],Z\\[1\\],Z\\[2\\]) and each subsequent row is  shifted by 1 (last row should be (Z\\[-3\\],Z\\[-2\\],Z\\[-1\\]) (★★★)     \n",
    "(**提示**: ```from numpy.lib import stride_tricks```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {
    "collapsed": true,
    "id": "24F51BFDF35845C6B71FEF2F66A63FFE",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# from numpy.lib import stride_tricks\n",
    "\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",
    "\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "07D09F00B9274F09B1A1A2438EF502E4",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 77. 如何对布尔值取反，或者原位(```in-place```)改变浮点数的符号(```sign```)？(★★★) \n",
    "(**提示**: ```np.logical_not, np.negative```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {
    "collapsed": true,
    "id": "1FF18DB3A6CD407983035E26C7DDC642",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.randint(0,2,100)\n",
    "# np.logical_not(Z, out=Z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {
    "collapsed": true,
    "id": "F2A7772989C9479A84D3281A9BDA4250",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.uniform(-1.0,1.0,100)\n",
    "# np.negative(Z, out=Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "F7238C25E1324E59B49A8246E0E1803D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 78. 考虑两组点集```P0```和```P1```去描述一组线(二维)和一个点```p```,如何计算点```p```到每一条线 i ```(P0[i],P1[i])```的距离？(★★★)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {
    "collapsed": true,
    "id": "2BE011F6ABE94E589F06CD32FD642C78",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# def distance(P0, P1, p):\n",
    "#     T = P1 - P0\n",
    "#     L = (T**2).sum(axis=1)\n",
    "#     U = -((P0[:,0]-p[...,0])*T[:,0] + (P0[:,1]-p[...,1])*T[:,1]) / L\n",
    "#     U = U.reshape(len(U),1)\n",
    "#     D = P0 + U*T - p\n",
    "#     return np.sqrt((D**2).sum(axis=1))\n",
    "\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",
    "# print (distance(P0, P1, p))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "313AF7F2B08D483F8DCAA199F0B647E3",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 79.考虑两组点集```P0```和```P1```去描述一组线(二维)和一组点集```P```，如何计算每一个点 ```j(P[j])``` 到每一条线 i ```(P0[i],P1[i]) ```的距离？(★★★)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {
    "collapsed": true,
    "id": "7C553C37C29C4080A48701D6042FDA31",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # based on distance function from previous question\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, (10,2))\n",
    "# print (np.array([distance(P0,P1,p_i) for p_i in p]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "405F07374A264727A590D94970B97AE5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 80.Consider an arbitrary array, write a function that extract a subpart with a fixed shape and centered on a given element (pad with a `fill` value when necessary) (★★★) \n",
    "(**hint**: minimum, maximum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {
    "collapsed": true,
    "id": "BAC016239FC347B486DD5AC4DA506AAE",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.randint(0,10,(10,10))\n",
    "# shape = (5,5)\n",
    "# fill  = 0\n",
    "# position = (1,1)\n",
    "\n",
    "# R = np.ones(shape, dtype=Z.dtype)*fill\n",
    "# P  = np.array(list(position)).astype(int)\n",
    "# Rs = np.array(list(R.shape)).astype(int)\n",
    "# Zs = np.array(list(Z.shape)).astype(int)\n",
    "\n",
    "# R_start = np.zeros((len(shape),)).astype(int)\n",
    "# R_stop  = np.array(list(shape)).astype(int)\n",
    "# Z_start = (P-Rs//2)\n",
    "# Z_stop  = (P+Rs//2)+Rs%2\n",
    "\n",
    "# R_start = (R_start - np.minimum(Z_start,0)).tolist()\n",
    "# Z_start = (np.maximum(Z_start,0)).tolist()\n",
    "# R_stop = np.maximum(R_start, (R_stop - np.maximum(Z_stop-Zs,0))).tolist()\n",
    "# Z_stop = (np.minimum(Z_stop,Zs)).tolist()\n",
    "\n",
    "# r = [slice(start,stop) for start,stop in zip(R_start,R_stop)]\n",
    "# z = [slice(start,stop) for start,stop in zip(Z_start,Z_stop)]\n",
    "# R[r] = Z[z]\n",
    "# print (Z)\n",
    "# print (R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "C9E524EE9063410582419C615ED27AA0",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 81. 考虑一个数组```Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]```,如何生成一个数组```R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ...,[11,12,13,14]]```? (★★★) \n",
    "(**提示**: ```stride_tricks.as_strided```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {
    "collapsed": true,
    "id": "43CDF04FE2394915A059DD1BB4C901EE",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(1,15,dtype=np.uint32)\n",
    "# R = stride_tricks.as_strided(Z,(11,4),(4,4))\n",
    "# print (R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "E2D036A1A89743EF9AD4C674B94FAD85",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 82. 计算一个矩阵的秩(★★★) \n",
    "(**提示**: ```np.linalg.svd```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {
    "collapsed": true,
    "id": "BCA339C5EA214E1E8E2CD7E83EC987DB",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.uniform(0,1,(10,10))\n",
    "# U, S, V = np.linalg.svd(Z) # Singular Value Decomposition\n",
    "# rank = np.sum(S > 1e-10)\n",
    "# print (rank)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "E25CC326657644A080330F9C5D37FC86",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 83. 如何找到一个数组中出现频率最高的值？ \n",
    "(**提示**: ```np.bincount, argmax```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {
    "collapsed": true,
    "id": "733C7593D0AF41938CA9CC3B456AE6F5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.randint(0,10,50)\n",
    "# print (np.bincount(Z).argmax())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A07EC615196149998A779CC23A664A7D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 84. 从一个```10x10```的矩阵中提取出连续的```3x3```区块(★★★) \n",
    "(**提示**: ```stride_tricks.as_strided```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {
    "collapsed": true,
    "id": "C6FF080800EF4CCA86BA7C46C2A0A4CF",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.randint(0,5,(10,10))\n",
    "# n = 3\n",
    "# i = 1 + (Z.shape[0]-3)\n",
    "# j = 1 + (Z.shape[1]-3)\n",
    "# C = stride_tricks.as_strided(Z, shape=(i, j, n, n), strides=Z.strides + Z.strides)\n",
    "# print (C)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "943C8A7CF29E4CBB98951A553E84EAE4",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 85. 创建一个满足 ```Z[i,j] == Z[j,i]```的子类 (★★★) \n",
    "(**提示**: ```class``` 方法)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {
    "collapsed": true,
    "id": "FB5B4EE1E960470485E204AB682E507E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# class Symetric(np.ndarray):\n",
    "#     def __setitem__(self, index, value):\n",
    "#         i,j = index\n",
    "#         super(Symetric, self).__setitem__((i,j), value)\n",
    "#         super(Symetric, self).__setitem__((j,i), value)\n",
    "\n",
    "# def symetric(Z):\n",
    "#     return np.asarray(Z + Z.T - np.diag(Z.diagonal())).view(Symetric)\n",
    "\n",
    "# S = symetric(np.random.randint(0,10,(5,5)))\n",
    "# S[2,3] = 42\n",
    "# print (S)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "60BB1B061FDA489D85A87463BB7A7B8D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 86. 考虑p个 ```nxn``` 矩阵和一组形状为```(n,1)```的向量，如何直接计算p个矩阵的乘积```(n,1)```？(★★★) \n",
    "(**提示**: ```np.tensordot```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {
    "collapsed": true,
    "id": "D6E9B8A3B69E41698447586FCF1E3B76",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# p, n = 10, 20\n",
    "# M = np.ones((p,n,n))\n",
    "# V = np.ones((p,n,1))\n",
    "# S = np.tensordot(M, V, axes=[[0, 2], [0, 1]])\n",
    "# print (S)\n",
    "# It works, because:\n",
    "# M is (p,n,n)\n",
    "# V is (p,n,1)\n",
    "# Thus, summing over the paired axes 0 and 0 (of M and V independently),\n",
    "# and 2 and 1, to remain with a (n,1) vector."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "E298E26CA8FC4D0A87CE17B3C8ED448A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 87. 对于一个```16x16```的数组，如何得到一个区域(```block-sum```)的和(区域大小为```4x4```)? (★★★) \n",
    "(**提示**: ```np.add.reduceat```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {
    "collapsed": true,
    "id": "B2B86B64BD1D4BA081132EFF55494EEF",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.ones((16,16))\n",
    "# k = 4\n",
    "# S = np.add.reduceat(np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0),\n",
    "#                                        np.arange(0, Z.shape[1], k), axis=1)\n",
    "# print (S)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "9733DB33A4FE41FA9B7A28BA6D9BA323",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 88. 如何利用```numpy```数组实现Game of Life? (★★★)\n",
    "(**提示**: [Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {
    "collapsed": true,
    "id": "B2F6FEF7398549F68F4281BC20B41165",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# def iterate(Z):\n",
    "#     # Count neighbours\n",
    "#     N = (Z[0:-2,0:-2] + Z[0:-2,1:-1] + Z[0:-2,2:] +\n",
    "#          Z[1:-1,0:-2]                + Z[1:-1,2:] +\n",
    "#          Z[2:  ,0:-2] + Z[2:  ,1:-1] + Z[2:  ,2:])\n",
    "\n",
    "#     # Apply rules\n",
    "#     birth = (N==3) & (Z[1:-1,1:-1]==0)\n",
    "#     survive = ((N==2) | (N==3)) & (Z[1:-1,1:-1]==1)\n",
    "#     Z[...] = 0\n",
    "#     Z[1:-1,1:-1][birth | survive] = 1\n",
    "#     return Z\n",
    "\n",
    "# Z = np.random.randint(0,2,(50,50))\n",
    "# for i in range(100): Z = iterate(Z)\n",
    "# print (Z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "05F350A2ECBF46928879CD5EC729C4C7",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 89. 如何找到一个数组的第n个最大值? (★★★) \n",
    "(**提示**: ```np.argsort | np.argpartition```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {
    "collapsed": true,
    "id": "AD514F23AA6A499D8FA7065841F72613",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.arange(10000)\n",
    "# np.random.shuffle(Z)\n",
    "# n = 5\n",
    "\n",
    "# # Slow\n",
    "# print (Z[np.argsort(Z)[-n:]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {
    "collapsed": true,
    "id": "203F24EA60A44E2580965FCFE02C757D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # 方法2\n",
    "# # Fast\n",
    "# print (Z[np.argpartition(-Z,n)[:n]])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A6B0BF5FA1EC4CAF9F77C9C2F503107A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 90. 给定任意个数向量，创建笛卡尔积(每一个元素的每一种组合)(★★★) \n",
    "(**提示**: ```np.indices```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {
    "collapsed": true,
    "id": "46D4E9E4169541228B2C40FF1CDBFA12",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# def cartesian(arrays):\n",
    "#     arrays = [np.asarray(a) for a in arrays]\n",
    "#     shape = (len(x) for x in arrays)\n",
    "\n",
    "#     ix = np.indices(shape, dtype=int)\n",
    "#     ix = ix.reshape(len(arrays), -1).T\n",
    "\n",
    "#     for n, arr in enumerate(arrays):\n",
    "#         ix[:, n] = arrays[n][ix[:, n]]\n",
    "\n",
    "#     return ix\n",
    "\n",
    "# print (cartesian(([1, 2, 3], [4, 5], [6, 7])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3D5B5652447848408AE38668828F97C9",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 91. 如何从一个正常数组创建记录数组(```record array```)? (★★★) \n",
    "(**提示**: ```np.core.records.fromarrays```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {
    "collapsed": true,
    "id": "82BEB0A109B149429DDC53232F28D63A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.array([(\"Hello\", 2.5, 3),\n",
    "#               (\"World\", 3.6, 2)])\n",
    "# R = np.core.records.fromarrays(Z.T, \n",
    "#                                names='col1, col2, col3',\n",
    "#                                formats = 'S8, f8, i8')\n",
    "# print (R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "D60D5195C1CA4ACE87B2B82D8C21D606",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 92. 考虑一个大向量```Z```, 用三种不同的方法计算它的立方(★★★) \n",
    "(**提示**: ```np.power, \\*, np.einsum```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {
    "collapsed": true,
    "id": "8519DE17751C4C6B859AEB7A94616D4C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# x = np.random.rand()\n",
    "# np.power(x,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {
    "collapsed": true,
    "id": "023FFA04A61143878DC019D3475C847B",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "## 方法2\n",
    "# x*x*x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {
    "collapsed": true,
    "id": "7F81104DAA2144368256477522F8E454",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "## 方法3\n",
    "# np.einsum('i,i,i->i',x,x,x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4D83EC574DF24D0F8DE19E9A91F096A4",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 93. 考虑两个形状分别为```(8,3)``` 和```(2,2)```的数组```A```和```B```. 如何在数组```A```中找到满足包含```B```中元素的行？(不考虑```B```中每行元素顺序)？ (★★★) \n",
    "(**提示**: ```np.where```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {
    "collapsed": true,
    "id": "06950269DCDF40E384834AE6F7D9D57E",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# A = np.random.randint(0,5,(8,3))\n",
    "# B = np.random.randint(0,5,(2,2))\n",
    "\n",
    "# C = (A[..., np.newaxis, np.newaxis] == B)\n",
    "# rows = np.where(C.any((3,1)).all(1))[0]\n",
    "# print (rows)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "50B173E09BE44D7B93B901D9915605C5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 94. 考虑一个```10x3```的矩阵，分解出有不全相同值的行 (如 ```[2,2,3]```) (★★★)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {
    "collapsed": true,
    "id": "67B07B2780C84116B8B3E114AA3F5D92",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.randint(0,5,(10,3))\n",
    "# print (Z)\n",
    "\n",
    "# # solution for arrays of all dtypes (including string arrays and record arrays)\n",
    "# E = np.all(Z[:,1:] == Z[:,:-1], axis=1)\n",
    "# U = Z[~E]\n",
    "# print (U)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {
    "collapsed": true,
    "id": "839AFE04281D430F84C10A037AEF405C",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # 方法2\n",
    "# # soluiton for numerical arrays only, will work for any number of columns in Z\n",
    "# U = Z[Z.max(axis=1) != Z.min(axis=1),:]\n",
    "# print (U)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3C438C79FF2442C18959B015D50B0382",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 95. 将一个整数向量转换为matrix binary的表现形式 (★★★) \n",
    "(**提示**: ```np.unpackbits```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {
    "collapsed": true,
    "id": "646F659946404BDA9AFFE725EA9E4018",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128])\n",
    "# B = ((I.reshape(-1,1) & (2**np.arange(8))) != 0).astype(int)\n",
    "# print(B[:,::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {
    "collapsed": true,
    "id": "067120D1D7034D9F817F06128D79E9E9",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# # 方法2\n",
    "# print (np.unpackbits(I[:, np.newaxis], axis=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "6B62627DE43347D29A80C9B864A53DDA",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 96. 给定一个二维数组，如何提取出唯一的(```unique```)行?(★★★) \n",
    "(**提示**: ```np.ascontiguousarray```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {
    "collapsed": true,
    "id": "9924218AF0644D8F93B01208B6807F03",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Z = np.random.randint(0,2,(6,3))\n",
    "# T = np.ascontiguousarray(Z).view(np.dtype((np.void, Z.dtype.itemsize * Z.shape[1])))\n",
    "# _, idx = np.unique(T, return_index=True)\n",
    "# uZ = Z[idx]\n",
    "# print (uZ)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "5A3738CBA4A349508E7C9F22B5F7166A",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 97. 考虑两个向量```A```和```B```，写出用```einsum```等式对应的```inner, outer, sum, mul```函数(★★★) \n",
    "(**提示**: [```np.einsum```](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.einsum.html))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {
    "collapsed": true,
    "id": "8E01F6B983C2426D9217504C83EEE486",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# A = np.random.uniform(0,1,10)\n",
    "# B = np.random.uniform(0,1,10)\n",
    "# print ('sum')\n",
    "# print (np.einsum('i->', A))# np.sum(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {
    "collapsed": true,
    "id": "69115798B9A044258DF261C172A4458B",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print ('A * B')\n",
    "# print (np.einsum('i,i->i', A, B)) # A * B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {
    "collapsed": true,
    "id": "02C2196DF276469E82B5F6EA24340250",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print ('inner')\n",
    "# print (np.einsum('i,i', A, B))    # np.inner(A, B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {
    "collapsed": true,
    "id": "DB99E8D722E442A89B4D782003EE53F6",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# print ('outer')\n",
    "# print (np.einsum('i,j->ij', A, B))    # np.outer(A, B)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "85C64AA83A824194816B708D36AB7E69",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 98. 考虑一个由两个向量描述的路径```(X,Y)```，如何用等距样例(```equidistant samples```)对其进行采样(```sample```)? (★★★)    \n",
    "Considering a path described by two vectors (X,Y), how to sample it using equidistant samples    \n",
    "(**提示**: ```np.cumsum, np.interp```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {
    "collapsed": true,
    "id": "B2CEA801F0164EEA854FBD8F684CA507",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# phi = np.arange(0, 10*np.pi, 0.1)\n",
    "# a = 1\n",
    "# x = a*phi*np.cos(phi)\n",
    "# y = a*phi*np.sin(phi)\n",
    "\n",
    "# dr = (np.diff(x)**2 + np.diff(y)**2)**.5 # segment lengths\n",
    "# r = np.zeros_like(x)\n",
    "# r[1:] = np.cumsum(dr)                # integrate path\n",
    "# r_int = np.linspace(0, r.max(), 200) # regular spaced path\n",
    "# x_int = np.interp(r_int, r, x)       # integrate path\n",
    "# y_int = np.interp(r_int, r, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "D5D0E40627A4435184C3813B775A14E5",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 99. Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n. (★★★)     \n",
    "(**提示**: ```np.logical_and.reduce, np.mod```)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {
    "collapsed": true,
    "id": "1C245E3CFF7D4EFF9913B886A0E8F7DB",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# X = np.asarray([[1.0, 0.0, 3.0, 8.0],\n",
    "#                 [2.0, 0.0, 1.0, 1.0],\n",
    "#                 [1.5, 2.5, 1.0, 0.0]])\n",
    "# n = 4\n",
    "# M = np.logical_and.reduce(np.mod(X, 1) == 0, axis=-1)\n",
    "# M &= (X.sum(axis=-1) == n)\n",
    "# print (X[M])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4A31C1F39DE44234BAF2F12720FEE07D",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "#### 100. 对于一个一维数组```X```，计算它boostrapped之后的95%置信区间的平均值。\n",
    "(Compute bootstrapped 95% confidence intervals for the mean of a 1D array X，i.e. resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means). (★★★)      \n",
    "(**提示**: ```np.percentile```)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {
    "collapsed": true,
    "id": "DFF4185E7EF1432D87EE695C4A972C39",
    "jupyter": {},
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# X = np.random.randn(100) # random 1D array\n",
    "# N = 1000 # number of bootstrap samples\n",
    "# idx = np.random.randint(0, X.size, (N, X.size))\n",
    "# means = X[idx].mean(axis=1)\n",
    "# confint = np.percentile(means, [2.5, 97.5])\n",
    "# print (confint)"
   ]
  }
 ],
 "metadata": {
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "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.5.2"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": "block",
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
