#!/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次