{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 数组形状" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using matplotlib backend: Qt4Agg\n", "Populating the interactive namespace from numpy and matplotlib\n" ] } ], "source": [ "%pylab" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 修改数组的形状" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2, 3, 4, 5])" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = arange(6)\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "将形状修改为2乘3:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 1, 2],\n", " [3, 4, 5]])" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.shape = 2,3\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "与之对应的方法是 `reshape` ,但它不会修改原来数组的值,而是返回一个新的数组:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 1],\n", " [2, 3],\n", " [4, 5]])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.reshape(3,2)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 1, 2],\n", " [3, 4, 5]])" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`shape` 和 `reshape` 方法不能改变数组中元素的总数,否则会报错:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ValueError", "evalue": "total size of new array must be unchanged", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0ma\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mValueError\u001b[0m: total size of new array must be unchanged" ] } ], "source": [ "a.reshape(4,2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 使用 newaxis 增加数组维数" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(3L,)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = arange(3)\n", "shape(a)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(1L, 3L)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = a[newaxis, :]\n", "shape(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "根据插入位置的不同,可以返回不同形状的数组:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(3L, 1L)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = a[:, newaxis]\n", "shape(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "插入多个新维度:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(1L, 1L, 3L)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = a[newaxis, newaxis, :]\n", "shape(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## squeeze 方法去除多余的轴" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "a = arange(6)\n", "a.shape = (2,1,3)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(2L, 3L)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = a.squeeze()\n", "b.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "squeeze 返回一个将所有长度为1的维度去除的新数组。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 数组转置" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "使用 `transpose` 返回数组的转置,本质上是将所有维度反过来:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[[0, 1, 2]],\n", "\n", " [[3, 4, 5]]])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "对于二维数组,这相当于交换行和列:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "array([[[0, 3]],\n", "\n", " [[1, 4]],\n", "\n", " [[2, 5]]])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.transpose()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "或者使用缩写属性:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[[0, 3]],\n", "\n", " [[1, 4]],\n", "\n", " [[2, 5]]])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.T" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "注意:\n", "- 对于复数数组,转置并不返回复共轭,只是单纯的交换轴的位置\n", "- 转置可以作用于多维数组" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n", " 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, 50,\n", " 51, 52, 53, 54, 55, 56, 57, 58, 59])" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = arange(60)\n", "a" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[[ 0, 1, 2, 3, 4],\n", " [ 5, 6, 7, 8, 9],\n", " [10, 11, 12, 13, 14],\n", " [15, 16, 17, 18, 19]],\n", "\n", " [[20, 21, 22, 23, 24],\n", " [25, 26, 27, 28, 29],\n", " [30, 31, 32, 33, 34],\n", " [35, 36, 37, 38, 39]],\n", "\n", " [[40, 41, 42, 43, 44],\n", " [45, 46, 47, 48, 49],\n", " [50, 51, 52, 53, 54],\n", " [55, 56, 57, 58, 59]]])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.shape = 3,4,5\n", "a" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(5L, 4L, 3L)" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = a.T\n", "b.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "转置只是交换了轴的位置。\n", "\n", "另一方面,转置返回的是对原数组的另一种view,所以改变转置会改变原来数组的值。" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 1, 2],\n", " [3, 4, 5]])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = arange(6)\n", "a.shape = (2,3)\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "修改转置:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "b = a.T\n", "b[0,1] = 30" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "原数组的值也改变:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2],\n", " [30, 4, 5]])" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 数组连接" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "有时我们需要将不同的数组按照一定的顺序连接起来:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " concatenate((a0,a1,...,aN), axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "注意,这些数组要用 `()` 包括到一个元组中去。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "除了给定的轴外,这些数组其他轴的长度必须是一样的。" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(2L, 3L)\n", "(2L, 3L)\n" ] } ], "source": [ "x = array([\n", " [0,1,2],\n", " [10,11,12]\n", " ])\n", "y = array([\n", " [50,51,52],\n", " [60,61,62]\n", " ])\n", "print x.shape\n", "print y.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "默认沿着第一维进行连接:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2],\n", " [10, 11, 12],\n", " [50, 51, 52],\n", " [60, 61, 62]])" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z = concatenate((x,y))\n", "z" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "(4L, 3L)" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "沿着第二维进行连接:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2, 50, 51, 52],\n", " [10, 11, 12, 60, 61, 62]])" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z = concatenate((x,y), axis=1)\n", "z" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(2L, 6L)" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "注意到这里 `x` 和 `y` 的形状是一样的,还可以将它们连接成三维的数组,但是 `concatenate` 不能提供这样的功能,不过可以这样:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true }, "outputs": [], "source": [ "z = array((x,y))" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(2L, 2L, 3L)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "事实上,**Numpy**提供了分别对应这三种情况的函数:\n", "\n", "- vstack\n", "- hstack\n", "- dstack" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(4L, 3L)" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vstack((x, y)).shape" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(2L, 6L)" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hstack((x, y)).shape" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(2L, 3L, 2L)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dstack((x, y)).shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Flatten 数组" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`flatten` 方法的作用是将多维数组转化为1维数组:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2, 3])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = array([[0,1],\n", " [2,3]])\n", "b = a.flatten()\n", "b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "返回的是数组的复制,因此,改变 `b` 并不会影响 `a` 的值:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[10 1 2 3]\n", "[[0 1]\n", " [2 3]]\n" ] } ], "source": [ "b[0] = 10\n", "print b\n", "print a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## flat 属性" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "还可以使用数组自带的 `flat` 属性:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.flat" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`a.flat` 相当于返回了所有元组组成的一个迭代器:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": true }, "outputs": [], "source": [ "b = a.flat" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "但此时修改 `b` 的值会影响 `a` :" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[10 1]\n", " [ 2 3]]\n" ] } ], "source": [ "b[0] = 10\n", "print a" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([10, 1, 2, 3])" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.flat[:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ravel 方法" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "除此之外,还可以使用 `ravel` 方法,`ravel` 使用高效的表示方式:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2, 3])" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = array([[0,1],\n", " [2,3]])\n", "b = a.ravel()\n", "b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "修改 `b` 会改变 `a` :" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[10, 1],\n", " [ 2, 3]])" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b[0] = 10\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "但另一种情况下:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([0, 2, 1, 3])" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = array([[0,1],\n", " [2,3]])\n", "aa = a.transpose()\n", "b = aa.ravel()\n", "b" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": true }, "outputs": [], "source": [ "b[0] = 10" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 2],\n", " [1, 3]])" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "aa" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[0, 1],\n", " [2, 3]])" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "可以看到,在这种情况下,修改 `b` 并不会改变 `aa` 的值,原因是我们用来 `ravel` 的对象 `aa` 本身是 `a` 的一个view。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## atleast_xd 函数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "保证数组至少有 `x` 维:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([1])" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 1\n", "atleast_1d(x)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(1L, 3L)" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = array([1,2,3])\n", "b = atleast_2d(a)\n", "b.shape" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[1, 2, 3]])" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": true }, "outputs": [], "source": [ "c = atleast_3d(b)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(1L, 3L, 1L)" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`x` 可以取值 1,2,3。\n", "\n", "在**Scipy**库中,这些函数被用来保证输入满足一定的条件:“ \n", "\n", "|用法|**Scipy**中出现次数|\n", "|-|-|\n", "|value.flaten()
value.flat
value.ravel() | ~2000次\n", "| atleast_1d(value)
atleast_2d(value) |~700次\n", "| asarray(value) |~4000次" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }