#!/usr/bin/env python # coding: utf-8 # # 数组形状 # In[1]: get_ipython().run_line_magic('pylab', '') # ## 修改数组的形状 # In[2]: a = arange(6) a # 将形状修改为2乘3: # In[3]: a.shape = 2,3 a # 与之对应的方法是 `reshape` ,但它不会修改原来数组的值,而是返回一个新的数组: # In[4]: a.reshape(3,2) # In[5]: a # `shape` 和 `reshape` 方法不能改变数组中元素的总数,否则会报错: # In[6]: a.reshape(4,2) # ## 使用 newaxis 增加数组维数 # In[7]: a = arange(3) shape(a) # In[8]: y = a[newaxis, :] shape(y) # 根据插入位置的不同,可以返回不同形状的数组: # In[9]: y = a[:, newaxis] shape(y) # 插入多个新维度: # In[10]: y = a[newaxis, newaxis, :] shape(y) # ## squeeze 方法去除多余的轴 # In[11]: a = arange(6) a.shape = (2,1,3) # In[12]: b = a.squeeze() b.shape # squeeze 返回一个将所有长度为1的维度去除的新数组。 # ## 数组转置 # 使用 `transpose` 返回数组的转置,本质上是将所有维度反过来: # In[13]: a # 对于二维数组,这相当于交换行和列: # In[14]: a.transpose() # 或者使用缩写属性: # In[15]: a.T # 注意: # - 对于复数数组,转置并不返回复共轭,只是单纯的交换轴的位置 # - 转置可以作用于多维数组 # In[16]: a = arange(60) a # In[17]: a.shape = 3,4,5 a # In[18]: b = a.T b.shape # 转置只是交换了轴的位置。 # # 另一方面,转置返回的是对原数组的另一种view,所以改变转置会改变原来数组的值。 # In[19]: a = arange(6) a.shape = (2,3) a # 修改转置: # In[20]: b = a.T b[0,1] = 30 # 原数组的值也改变: # In[21]: a # ## 数组连接 # 有时我们需要将不同的数组按照一定的顺序连接起来: # concatenate((a0,a1,...,aN), axis=0) # 注意,这些数组要用 `()` 包括到一个元组中去。 # 除了给定的轴外,这些数组其他轴的长度必须是一样的。 # In[22]: x = array([ [0,1,2], [10,11,12] ]) y = array([ [50,51,52], [60,61,62] ]) print x.shape print y.shape # 默认沿着第一维进行连接: # In[23]: z = concatenate((x,y)) z # In[24]: z.shape # 沿着第二维进行连接: # In[25]: z = concatenate((x,y), axis=1) z # In[26]: z.shape # 注意到这里 `x` 和 `y` 的形状是一样的,还可以将它们连接成三维的数组,但是 `concatenate` 不能提供这样的功能,不过可以这样: # In[27]: z = array((x,y)) # In[28]: z.shape # 事实上,**Numpy**提供了分别对应这三种情况的函数: # # - vstack # - hstack # - dstack # In[29]: vstack((x, y)).shape # In[30]: hstack((x, y)).shape # In[31]: dstack((x, y)).shape # ## Flatten 数组 # `flatten` 方法的作用是将多维数组转化为1维数组: # In[32]: a = array([[0,1], [2,3]]) b = a.flatten() b # 返回的是数组的复制,因此,改变 `b` 并不会影响 `a` 的值: # In[33]: b[0] = 10 print b print a # ## flat 属性 # 还可以使用数组自带的 `flat` 属性: # In[34]: a.flat # `a.flat` 相当于返回了所有元组组成的一个迭代器: # In[35]: b = a.flat # In[36]: b[0] # 但此时修改 `b` 的值会影响 `a` : # In[37]: b[0] = 10 print a # In[38]: a.flat[:] # ## ravel 方法 # 除此之外,还可以使用 `ravel` 方法,`ravel` 使用高效的表示方式: # In[39]: a = array([[0,1], [2,3]]) b = a.ravel() b # 修改 `b` 会改变 `a` : # In[40]: b[0] = 10 a # 但另一种情况下: # In[41]: a = array([[0,1], [2,3]]) aa = a.transpose() b = aa.ravel() b # In[42]: b[0] = 10 # In[43]: aa # In[44]: a # 可以看到,在这种情况下,修改 `b` 并不会改变 `aa` 的值,原因是我们用来 `ravel` 的对象 `aa` 本身是 `a` 的一个view。 # ## atleast_xd 函数 # 保证数组至少有 `x` 维: # In[45]: x = 1 atleast_1d(x) # In[46]: a = array([1,2,3]) b = atleast_2d(a) b.shape # In[47]: b # In[48]: c = atleast_3d(b) # In[49]: c.shape # `x` 可以取值 1,2,3。 # # 在**Scipy**库中,这些函数被用来保证输入满足一定的条件:“ # # |用法|**Scipy**中出现次数| # |-|-| # |value.flaten()
value.flat
value.ravel() | ~2000次 # | atleast_1d(value)
atleast_2d(value) |~700次 # | asarray(value) |~4000次