1、索引、切片、迭代
一维数组可以被索引、切片、迭代,这和list等的python序列有点像
>>> a = np.arange(10)**3
>>> a
array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729])
>>> a[2]
8
>>> a[2:5]
array([ 8, 27, 64])
>>> a[:6:2] = -1000 # 等价于a[0:6:2],从0到6,依次增长2 将这些对应的元素置为-1000
>>> a
array([-1000, 1, -1000, 27, -1000, 125, 216, 343, 512, 729])
>>> a[ : :-1] # 将a 倒置
array([ 729, 512, 343, 216, 125, -1000, 27, -1000, 1, -1000])
>>> for i in a:
... print(i**(1/3.))
...
nan
1.0
nan
3.0
nan
5.0
6.0
7.0
8.0
9.0343 512 729]
2、多维数组每轴可以有一个索引,这些索引以逗号分隔的索引给出
>>> def f(x,y):
... return 10*x+y
...
>>> b = np.fromfunction(f,(5,4),dtype=int)
>>> b
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33],
[40, 41, 42, 43]])
>>> b[2,3]
23
>>> b[0:5, 1] #第一列的0到5行(不包含第5行)
array([ 1, 11, 21, 31, 41])
>>> b[ : ,1] # ‘:’ 对应的维度全取,所以b[ : ,1]相当于数组的第一列
array([ 1, 11, 21, 31, 41])
>>> b[1:3, : ] # 第一行和第二行的所有元素
array([[10, 11, 12, 13],
[20, 21, 22, 23]])
当给出的索引个数小于数组的维数时,缺失的部分被认为全取
b[-1] # 最后一行,相当于b[-1,:]
array([40, 41, 42, 43])
表达式b[i] 被默认为,取第i维度的所有元素,Numpy也允许把这个写成b[1,…]
点(…)代表产生完整索引元组所需的冒号数量。 例如,如果x是rank 5数组(即它有5个轴),那么 :
x[1,2,…] 等价于 x[1,2,:,:,:]
x[…,3] 等价于 x[:,:,:,:,3]
x[4,…,5,:] 等价于 x[4,:,:,5,:].
c = np.array( [[[ 0, 1, 2], #一个三维数组是由两个二维数组
... [ 10, 12, 13]],
... [[100,101,102],
... [110,112,113]]])
>>> c.shape
(2, 2, 3)
>>> c[1,...] # 和c[1,:,:] 或者 c[1]相同
array([[100, 101, 102],
[110, 112, 113]])
>>> c[...,2] # 和 c[:,:,2] 相同
array([[ 2, 13],
[102, 113]])
多维数组的迭代是针对第一维度的
for row in b:
... print(row)
...
[0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]
如果想要将数组的所有元素一个一个输出,可以使用属性flat(所有元素的迭代器)
>>> for element in b.flat:
... print(element)
...
0
1
2
3
10
11
12
13
20
21
22
23
30
31
32
33
40
41
42
43
2、数组形状修改
每个轴(维度)元素的数量 确定了数组的大小
a = np.floor(10*np.random.random((3,4)))
>>> a
array([[ 2., 8., 0., 6.],
[ 4., 5., 1., 1.],
[ 8., 9., 3., 6.]]) #floor为向左取整
>>> a.shape
(3, 4)
可以通过多种命令修改数组的形状,下面的三种就能修改,但是并不会修改原始数组的形状
>>> a.ravel() #返回一个新的数组,水平化了的
array([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.])
>>> a.reshape(6,2) # 返回一个形状被修改的数组
array([[ 2., 8.],
[ 0., 6.],
[ 4., 5.],
[ 1., 1.],
[ 8., 9.],
[ 3., 6.]])
>>> a.T # returns the array, transposed
array([[ 2., 4., 8.],
[ 8., 5., 9.],
[ 0., 1., 3.],
[ 6., 1., 6.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4)
由ravel()产生的数组中的元素的顺序通常是“C风格”,即最右边的索引“改变最快”,所以在[0,0]之后的元素是[0,1]。 如果将数组重新整形为其他形状,则将该数组视为“C风格”。 NumPy通常会创建以这个顺序存储的数组,所以ravel()通常不需要复制其参数,但是如果数组是通过采用另一个数组的片段创建的,或者是通过异常选项创建的,则可能需要复制它们。 也可以使用可选参数来指示函数ravel()和reshape()来使用FORTRAN样式的数组,其中最左边的索引的变化最快。
reshape函数返回修改形状过后的数组,而ndarray.resize方法会修改数组本身:
>>> a
array([[ 2., 8., 0., 6.],
[ 4., 5., 1., 1.],
[ 8., 9., 3., 6.]])
>>> a.resize((2,6))
>>> a
array([[ 2., 8., 0., 6., 4., 5.], #数组本身被修改
[ 1., 1., 8., 9., 3., 6.]])
在使用reshape 时,如果在索引过程中哪个值给了 -1,数组将会自动计算出来正确的结果
>>> a.reshape(3,-1)
array([[ 2., 8., 0., 6.],
[ 4., 5., 1., 1.],
[ 8., 9., 3., 6.]])
3、堆叠不同的阵列
几个阵列可以沿着不同的轴堆叠在一起:
>>> a = np.floor(10*np.random.random((2,2)))
>>> a
array([[ 8., 8.],
[ 0., 0.]])
>>> b = np.floor(10*np.random.random((2,2)))
>>> b
array([[ 1., 8.],
[ 0., 4.]])
>>> np.vstack((a,b))
array([[ 8., 8.],
[ 0., 0.],
[ 1., 8.],
[ 0., 4.]])
>>> np.hstack((a,b))
array([[ 8., 8., 1., 8.],
[ 0., 0., 0., 4.]])
函数column_stack将一维数组作为列堆叠成二维数组。 它相当于仅用于一维阵列的vstack:
>>> from numpy import newaxis
>>> np.column_stack((a,b)) # With 2D arrays
array([[ 8., 8., 1., 8.],
[ 0., 0., 0., 4.]])
>>> a = np.array([4.,2.])
>>> b = np.array([2.,8.])
>>> a[:,newaxis] # This allows to have a 2D columns vector
array([[ 4.],
[ 2.]])
>>> np.column_stack((a[:,newaxis],b[:,newaxis]))
array([[ 4., 2.],
[ 2., 8.]])
>>> np.vstack((a[:,newaxis],b[:,newaxis])) # The behavior of vstack is different
array([[ 4.],
[ 2.],
[ 2.],
[ 8.]])
在复杂情况下,r_和c_对于通过沿一个轴堆叠数字来创建数组很有用。 它们允许使用范围文字(“:”)
>>> np.r_[1:4,0,4]
array([1, 2, 3, 0, 4])
将数组分割成几个小部分
使用hsplit,您可以沿着水平轴拆分数组,方法是指定要返回的等同数组的数量,或者指定分隔之后的列:
>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[ 9., 5., 6., 3., 6., 8., 0., 7., 9., 7., 2., 7.],
[ 1., 4., 9., 2., 2., 1., 0., 6., 2., 2., 4., 0.]])
>>> np.hsplit(a,3) # 拆分为 3个
[array([[ 9., 5., 6., 3.],
[ 1., 4., 9., 2.]]), array([[ 6., 8., 0., 7.],
[ 2., 1., 0., 6.]]), array([[ 9., 7., 2., 7.],
[ 2., 2., 4., 0.]])]
>>> np.hsplit(a,(3,4)) #在第三之前和第四列之后拆分
[array([[ 9., 5., 6.],
[ 1., 4., 9.]]), array([[ 3.],
[ 2.]]), array([[ 6., 8., 0., 7., 9., 7., 2., 7.],
[ 2., 1., 0., 6., 2., 2., 4., 0.]])]
vsplit沿着垂直轴分割,而array_split允许用来指定要分割的轴。