NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。
Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有一些额外的功能。 2005年,Travis Oliphant 通过将 Numarray 的功能集成到 Numeric 包中来创建 NumPy 包。 这个开源项目有很多贡献者。
使用NumPy,开发人员可以执行以下操作:
NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用。 这种组合广泛用于替代 MatLab,是一个流行的技术计算平台。 但是,Python 作为 MatLab 的替代方案,现在被视为一种更加现代和完整的编程语言。
NumPy 是开源的,这是它的一个额外的优势
NumPy 中定义的最重要的对象是称为 ndarray 的 N 维数组类型。 它描述相同类型的元素集合(笔记:固定类型元素的组合;采用C语言的数组形式)。 可以使用基于零的索引访问集合中的项目。
ndarray中的每个元素在内存中使用相同大小的块。 ndarray中的每个元素是数据类型对象的对象(称为 dtype)。
从ndarray对象提取的任何元素(通过切片)由一个数组标量类型的 Python 对象表示。
下图显示了ndarray,数据类型对象(dtype)和数组标量类型之间的关系。
Ndarray (笔记:Ndarray 即 numpy data array)
ndarray类的实例可以通过本教程后面描述的不同的数组创建例程来构造。 基本的ndarray是使用 NumPy 中的数组函数创建的,如下所示:
# python
# 笔记:创建一个空ndarray对象
numpy.array
它从任何暴露数组接口的对象,或从返回数组的任何方法创建一个ndarray。
( 笔记:
通过拷贝其他数组对象object来创建一个ndarray对象
暴露接口:
就是你写好了一段程序,提供给别人一个访问的接口,别人不管你怎么实现的,调用者只需知道访问的方法及返回值就可以。如:你写的方法
public int sum(int a,int b){
int c = 0;
....
return c;
}
调用者不管你sum怎么实现,只需知道sum()需要两个int参数,返回值是int即可。
那么,暴露数组接口 即可以理解为返回值为数组的接口。
)
# Python
# 笔记:创建一个ndarray对象,并用object对其进行初始化
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
上面的构造器接受以下参数:
看看下面的例子来更好地理解。
import numpy as np
a = np.array([1,2,3]) # 采用暴露数组接口的方式创建ndarray
print a
# 输出如下:
[1, 2, 3]
# 多于一个维度
import numpy as np
a = np.array([[1, 2], [3, 4]]) # 二维数组
print a
# 输出如下:
[[1, 2]
[3, 4]]
# 最小维度
import numpy as np
a = np.array([1, 2, 3, 4, 5], ndmin = 2) # 最小维度为2
print a
# 输出如下:
[[1, 2, 3, 4, 5]]
# 笔记:最小维度为2,但是创建时只用了一维数组,因此ndarray会有一个空维度,即:[ [1, 2, 3, 4, 5] [] ],空维度不显示所以成如上显示
# dtype 参数
import numpy as np
a = np.array([1, 2, 3], dtype = complex) # 设置类型 complex表示复数; 创建时,将元素转换为负数
print a
# 输出如下:
[ 1.+0.j, 2.+0.j, 3.+0.j]
**ndarray ** 对象由计算机内存中的一维连续区域组成,带有将每个元素映射到内存块中某个位置的索引方案。 内存块以按行(C 风格)或按列(FORTRAN 或 MatLab 风格)的方式保存元素。
NumPy 支持比 Python 更多种类的数值类型。 下表显示了 NumPy 中定义的不同标量数据类型。
名称 | 描述 |
---|---|
bool_ | 布尔型数据类型(True 或者 False) |
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) |
intc | 与 C 的 int 类型一样,一般是 int32 或 int 64 |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64) |
int8 | 字节(-128 to 127) |
int16 | 整数(-32768 to 32767) |
int32 | 整数(-2147483648 to 2147483647) |
int64 | 整数(-9223372036854775808 to 9223372036854775807) |
uint8 | 无符号整数(0 to 255) |
uint16 | 无符号整数(0 to 65535) |
uint32 | 无符号整数(0 to 4294967295) |
uint64 | 无符号整数(0 to 18446744073709551615) |
float_ | float64 类型的简写 |
float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
complex_ | complex128 类型的简写,即 128 位复数 |
complex64 | 复数,表示双 32 位浮点数(实数部分和虚数部分) |
complex128 | 复数,表示双 64 位浮点数(实数部分和虚数部分) |
NumPy 数字类型是dtype(数据类型)对象的实例,每个对象具有唯一的特征。 这些类型可以是np.bool_,np.float32等。
数据类型对象(dtype)描述了对应于数组的固定内存块的解释(笔记:参考上图,更易理解),取决于以下方面:
字节顺序取决于数据类型的前缀<或>。
dtype可由一下语法构造:
numpy.dtype(object, align, copy)
参数为:
Object:被转换为数据类型的对象。
Align:如果为true,则向字段添加间隔,使其类似 C 的结构体。
Copy: 生成dtype对象的新副本,如果为flase,结果是内建数据类型对象的引用。
# 使用数组标量类型
import numpy as np
dt = np.dtype(np.int32)
print dt
# 输出如下:
int32
笔记:int8,int16,int32,int64 可替换为等价的字符串 ‘i1’,‘i2’,‘i4’,以及其他。 i1 中 1表示1个字节,1个字节为8位,因此 i1 等价于 int8
#int8,int16,int32,int64 可替换为等价的字符串 'i1','i2','i4',以及其他。
import numpy as np
dt = np.dtype('i4') # int32 即:4字节*8位
print dt
#输出如下:
int32
# 使用端记号
import numpy as np
dt = np.dtype('>i4')
print dt
# 输出如下:
>i4
笔记:端记号的作用??
下面的例子展示了结构化数据类型的使用。 这里声明了字段名称和相应的标量数据类型。
笔记:所谓结构化数据类型,即:多种数据类型的结构体。注意:定义结构化类型时,方括号的使用。例如:[ (‘age’, np.int8) ] ,方括号内还有一层小括号。方括号表示为列表,小括号为元组
# 首先创建结构化数据类型。
import numpy as np
dt = np.dtype([('age',np.int8)]) # 注意:定义结构化类型时,方括号的使用。[('age',np.int8)] 方括号内还有一层小括号
print dt
# 输出如下:
[('age', 'i1')]
# 现在将其应用于 ndarray 对象
import numpy as np
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt) # 没理解 dt结构化类型 如何定义的ndarray的元素?
print a
# 输出如下:
[(10,) (20,) (30,)]
笔记:没理解 dt结构化类型 如何定义的ndarray的元素?
看下例,解释了age的作用,‘age’原来作为列名使用。即,age = [10 20 30]。
[(10,),(20,),(30,)] 的排列结构:
列 0 列名:‘age’ | 列 1 列名:null | |
---|---|---|
行0 | 10 | null |
行1 | 20 | null |
行2 | 30 | null |
# 文件名称可用于访问 age 列的内容
import numpy as np
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print a['age']
# 输出如下:
[10 20 30] # 有疑惑看上例
以下示例定义名为 student 的结构化数据类型,其中包含字符串字段name,整数字段age和浮点字段marks。 此dtype应用于ndarray对象。
import numpy as np
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
print student
# 输出如下:
[('name', 'S20'), ('age', 'i1'), ('marks', ')])
import numpy as np
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student)
print a
#输出如下:
[('abc', 21, 50.0), ('xyz', 18, 75.0)]
每个内建类型都有一个唯一定义它的字符代码:
这一章中,我们会讨论 NumPy 的多种数组属性。
这一数组属性返回一个包含数组维度的元组,它也可以用于调整数组大小。
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print a.shape # 注意:a.shape是数组a的属性,返回一个元组,该元组包含数组维度。
# 输出如下:
(2, 3)
# 这会调整数组大小
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
a.shape = (3,2) # 调整数组 矩阵
print a
# 输出如下:
[[1, 2]
[3, 4]
[5, 6]]
NumPy 也提供了reshape函数来调整数组大小。
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2) # 也可以写为:a.shape = (3,2) b = a
print b
# 输出如下:
[[1, 2]
[3, 4]
[5, 6]]
这一数组属性返回数组的维数。
# 等间隔数字的数组
import numpy as np
a = np.arange(24) # 一种初始化数组的方法
print a
#输出如下:
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
# 一维数组
import numpy as np
a = np.arange(24)
print(a.ndim)
# 现在调整其大小
b = a.reshape(2,4,3)
print(b)
# 输出如下:
1 # print(a.ndim)
[[[ 0, 1, 2] # print(b) 三维数组
[ 3, 4, 5]
[ 6, 7, 8]
[ 9, 10, 11]]
[[12, 13, 14]
[15, 16, 17]
[18, 19, 20]
[21, 22, 23]]]
这一数组属性返回数组中每个元素的字节单位长度。
# 数组的 dtype 为 int8(一个字节)
import numpy as np
x = np.array([1,2,3,4,5], dtype = np.int8)
print x.itemsize
# 输出如下: 8位一个字节,因此x.itemsize = 1
1
# 数组的 dtype 现在为 float32(四个字节)
import numpy as np
x = np.array([1,2,3,4,5], dtype = np.float32)
print x.itemsize
# 输出如下:
4
ndarray对象拥有以下属性。这个函数返回了它们的当前值。
序号 | 属性及描述 |
---|---|
C_CONTIGUOUS ( C) | 数组位于单一的、C 风格的连续区段内 |
F_CONTIGUOUS (F) | 数组位于单一的、Fortran 风格的连续区段内 |
OWNDATA (O) | 数组的内存从其它对象处借用 |
WRITEABLE (W) | 数据区域可写入。 将它设置为flase会锁定数据,使其只读 |
ALIGNED (A) | 数据和任何元素会为硬件适当对齐 |
UPDATEIFCOPY (U) | 这个数组是另一数组的副本。当这个数组释放时,源数组会由这个数组中的元素更新 |
下面的例子展示当前的标志。
import numpy as np
x = np.array([1,2,3,4,5])
print x.flags
# 输出如下:
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
新的ndarray对象可以通过任何下列数组创建例程或使用低级ndarray构造函数构造。
它创建指定形状和dtype的未初始化数组。 它使用以下构造函数:
numpy.empty(shape, dtype = float, order = 'C')
构造器接受下列参数:
序号 | 参数及描述 |
---|---|
shape | 空数组的形状,整数或整数元组 |
dtype | 所需的输出数组类型,可选 |
order | 'C’为按行的 C 风格数组,'F’为按列的 Fortran 风格数组 |
下面的代码展示空数组的例子:
import numpy as np
x = np.empty([3,2], dtype = int) # 创建未初始化的数组
print (x)
#输出如下: 因为未被初始化,所以
[[1701336096 1634235168]
[1864394096 1752440934]
[1701716069 1918967927]]
注意:数组元素为随机值,因为它们未初始化。
返回特定大小,以 0 填充的新数组。
numpy.zeros(shape, dtype = float, order = 'C')
构造器接受下列参数:同numpy.empty方法
# 含有 5 个 0 的数组,默认类型为 float
import numpy as np
x = np.zeros(5) # 默认:dtype = float
print (x)
# 输出如下:
[ 0. 0. 0. 0. 0.]
import numpy as np
x = np.zeros((5,), dtype = np.int)
print x
输出如下:
[0 0 0 0 0]
# 自定义类型
import numpy as np
x = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')]) #笔记:元素自定义类型,一个元素有2组变量 名称为x的一组,y为另一组
print (x)
print(x['x']) # 元素的名称输出
# 输出如下:
[[(0,0)(0,0)] # print (x)
[(0,0)(0,0)]]
[[0 0] # print(x['x']) # 元素的名称输出
[0 0]]
返回特定大小,以 1 填充的新数组。
numpy.ones(shape, dtype = None, order = 'C')
构造器接受下列参数:同np.zeros() 和np.empty()
笔记:numpy.ones()方法的dtype属性默认值为float(测试验证),此处于np.zeros() 和np.empty()相同。
# 含有 5 个 1 的数组,默认类型为 float
import numpy as np
x = np.ones(5)
print(x)
#输出如下:
[ 1. 1. 1. 1. 1.]
import numpy as np
x = np.ones([2,2], dtype = int)
print(x)
# 输出如下:
[[1 1]
[1 1]]
这一章中,我们会讨论如何从现有数据创建数组。
此函数类似于numpy.array,除了它有较少的参数。 这个例程对于将 Python 序列转换为ndarray非常有用。
numpy.asarray(a, dtype = None, order = None)
构造器接受下列参数:
下面的例子展示了如何使用asarray函数:
# 将列表转换为 ndarray
import numpy as np
x = [1,2,3] # python list
a = np.asarray(x)
print(a)
# 输出如下:
[1 2 3]
# 设置了 dtype
import numpy as np
x = [1,2,3]
a = np.asarray(x, dtype = float)
print a
# 输出如下:
[ 1. 2. 3.]
# 来自元组的 ndarray
import numpy as np
x = (1,2,3)
a = np.asarray(x)
print(a)
# 输出如下:
[1 2 3]
# 来自元组列表的 ndarray
import numpy as np
x = [(1,2,3),(4,5)]
a = np.asarray(x)
print a
# 输出如下:
[(1, 2, 3) (4, 5)]
此函数将缓冲区解释为一维数组。 暴露缓冲区接口的任何对象都用作参数来返回ndarray。
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
构造器接受下列参数:
序号 参数及描述
下面的例子展示了frombuffer函数的用法。
import numpy as np
s = 'Hello World'
a = np.frombuffer(s, dtype = 'S1')
print(a)
# 输出如下:
['H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd']
import numpy as np
...
img_buff = (c_ubyte * st_convert_param.nDstBufferSize)() # 创建c_ubyte类型图像缓存区
cdll.msvcrt.memcpy(byref(img_buff), st_convert_param.pDstBuffer, st_convert_param.nDstBufferSize) # 为图像缓冲区赋值
# img_buff 转为 numpy类型
img_buff = numpy.frombuffer(img_buff, count=int(st_convert_param.nDstBufferSize), dtype=numpy.uint8)
# 重构
img_buff = img_buff.reshape((frame_info.nHeight, frame_info.nWidth))
...
此函数从任何可迭代对象构建一个ndarray对象,返回一个新的一维数组。
numpy.fromiter(iterable, dtype, count = -1)
构造器接受下列参数:
以下示例展示了如何使用内置的range()函数返回列表对象。 此列表的迭代器用于形成ndarray对象。
# 使用 range 函数创建列表对象
import numpy as np
list = range(5)
print list
# 输出如下:
[0, 1, 2, 3, 4]
# 从列表中获得迭代器
import numpy as np
list = range(5)
it = iter(list) # 创建迭代器
# 使用迭代器创建 ndarray
x = np.fromiter(it, dtype = float)
print(x)
# 输出如下:
[0. 1. 2. 3. 4.]
这一章中,我们会学到如何从数值范围创建数组。
这个函数返回ndarray对象,包含给定范围内的等间隔值。
numpy.arange(start, stop, step, dtype)
构造器接受下列参数:
下面的例子展示了如何使用该函数:
import numpy as np
x = np.arange(5)
print(x)
# 输出如下:
[0 1 2 3 4]
import numpy as np
# 设置了 dtype
x = np.arange(5, dtype = float)
print(x)
# 输出如下:
[0. 1. 2. 3. 4.]
# 设置了起始值和终止值参数
import numpy as np
x = np.arange(10,20,2)
print(x)
# 输出如下:
[10 12 14 16 18]
此函数类似于arange()函数。 在此函数中,指定了范围之间的均匀间隔数量,而不是步长。 此函数的用法如下。
笔记:linspace()的特点是 均匀间隔,也就是说不需要设置步长,设置中间有多少个数(均匀间隔数量)就可以了。
numpy.linspace(start, stop, num, endpoint, retstep, dtype)
构造器接受下列参数:
下面的例子展示了linspace函数的用法。
import numpy as np
x = np.linspace(10,20,5) # 默认endpoint = true, 包含终止值20; 默认dtype=float
print x
# 输出如下:
[10. 12.5 15. 17.5 20.]
# 将 endpoint 设为 false
import numpy as np
x = np.linspace(10, 20, 5, endpoint = False) # 不包含最后一个数20
print(x)
# 输出如下:
[10. 12. 14. 16. 18.]
笔记:步长是等距间隔,不需要人工输出,但是将 retstep = True,可以输出该步长。
# 输出 retstep 值
import numpy as np
x = np.linspace(1,2,5, retstep = True)
print x
# 这里的 retstep 为 0.25
# 输出如下:
(array([ 1. , 1.25, 1.5 , 1.75, 2. ]), 0.25)
此函数返回一个ndarray对象,其中包含在对数刻度上均匀分布的数字。 刻度的开始和结束端点是某个底数的幂,通常为 10。
numpy.logscale(start, stop, num, endpoint, base, dtype)
logspace函数的输出由以下参数决定:
下面的例子展示了logspace函数的用法。
import numpy as np
# 默认底数是 10
a = np.logspace(1.0, 2.0, num = 10)
print a
# 输出如下:
[ 10. 12.91549665 16.68100537 21.5443469 27.82559402
35.93813664 46.41588834 59.94842503 77.42636827 100. ]
# 将对数空间的底数设置为 2
import numpy as np
a = np.logspace(1,10,num = 10, base = 2)
print a
# 输出如下:
[ 2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.]
ndarray对象的内容可以通过索引或切片来访问和修改,就像 Python 的内置容器对象一样。
如前所述,ndarray对象中的元素遵循基于零的索引。
有三种可用的索引方法类型:
基本切片是 Python 中基本切片概念到 n 维的扩展。 通过将start,stop和step参数提供给内置的slice函数来构造一个 Python slice对象。 此slice对象被传递给数组来提取数组的一部分。
import numpy as np
a = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
s = slice(2,7,2) # 创造切片。参数:起始,终止和步长
print a[s] # 获得a的s切片
# 输出如下:
[2 4 6]
在上面的例子中,ndarray对象由arange()函数创建。
然后,分别用起始,终止和步长值2,7和2定义切片对象。 当这个切片对象传递给ndarray时,会对它的一部分进行切片,从索引2到7,步长为2。
通过将由冒号分隔的切片参数(start:stop:step)直接提供给ndarray对象,也可以获得相同的结果。
import numpy as np
a = np.arange(10)
b = a[2:7:2] # 等效于 s = slice(2,7,2) a[s]
# [起始:终止:步长] 可以只写需要的部分
print b
# 输出如下:
[2 4 6]
如果只输入一个参数,则将返回与索引对应的单个项目。 如果使用a:,则从该索引向后的所有项目将被提取。 如果使用两个参数(以:分隔),则对两个索引(不包括停止索引)之间的元素以默认步骤进行切片。
# 对单个元素进行切片
import numpy as np
a = np.arange(10)
b = a[5]
print b
# 输出如下:
5
# 对始于索引的元素进行切片
import numpy as np
a = np.arange(10)
print a[2:]
# 输出如下:
[2 3 4 5 6 7 8 9]
# 对索引之间的元素进行切片
import numpy as np
a = np.arange(10)
print a[2:5]
# 输出如下:
[2 3 4]
上面的描述也可用于多维ndarray。
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
# 对始于索引的元素进行切片
print '现在我们从索引 a[1:] 开始对数组切片'
print (a[1:])
# 输出如下: # print(a)
[[1 2 3]
[3 4 5]
[4 5 6]]
现在我们从索引 a[1:] 开始对数组切片
# print (a[1:])
[[3 4 5]
[4 5 6]]
笔记:在多维数组切片时,第一维切片例如a[1:] 中1表示切片第一维数组的第二个元素值开始至最后一个元素;那么第二维切片怎么表示呢?
第二维切片,例如a[…,1]中“逗号”后面的1表示第二维度数组的第二个元素。由此可见,**“逗号”**是区分维度的关键。再例如a[…,1:]因为1后面多了“:”则表示第二维度数组的第二个元素开始至最后一个元素;
切片还可以包括省略号(…),来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的ndarray。
# 最开始的数组
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print '我们的数组是:'
print a
print '\n'
# 这会返回第二列元素的数组:
print '第二列的元素是:'
print a[...,1] # 切片包含省略号(...),来使选择元组的长度与数组的维度相同。
print '\n'
# 现在我们从第二行切片所有元素:
print '第二行的元素是:'
print a[1,...]
print '\n'
# 现在我们从第二列向后切片所有元素:
print '第二列及其剩余元素是:'
print a[...,1:]
#输出如下:
我们的数组是: # print(a)
[[1 2 3]
[3 4 5]
[4 5 6]]
第二列的元素是: # print a[...,1]
[2 4 5]
第二行的元素是: # print a[1,...]
[3 4 5]
第二列及其剩余元素是:
[[2 3]
[4 5]
[5 6]]
如果一个ndarray是非元组序列,数据类型为整数或布尔值的ndarray,或者至少一个元素为序列对象的元组,我们就能够用它来索引ndarray。高级索引始终返回数据的副本。 与此相反,切片只提供了一个视图。
有两种类型的高级索引:
这种机制有助于基于 N 维索引来获取数组中任意元素。 每个整数数组表示该维度的下标值。 当索引的元素个数就是目标ndarray的维度时,会变得相当直接。
以下示例获取了ndarray对象中每一行指定列的一个元素。 因此,行索引包含所有行号,列索引指定要选择的元素。
笔记:此种方法获得一维数组
import numpy as np
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0,1,2], [0,1,0]]
'''
笔记:理解下标矩阵
[[0,1,2], [0,1,0]] 组成了一个二维下标矩阵
[0,1,2] 为第一维下标队列
[0,1,0] 为第二维下标队列
组合为矩阵后,列1为 第一维下标队列,列2为 第二维下标队列
(0,0)
(1,1)
(2,0)
'''
print y
# 输出如下:
[1 4 5] # 获得的是一维数组
该结果包括数组中(0,0),(1,1)和(2,0)位置处的元素。
下面的示例获取了 4X3 数组中的每个角处的元素。 行索引是[0,0]和[3,3],而列索引是[0,2]和[0,2]。
笔记:此种方法获得二维数组
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print ('我们的数组是:')
print (x)
print ('\n')
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]
'''
笔记:理解行列下标矩阵
rows获得据矩阵为
0,0
3,3
cols获得的矩阵为
0,2
0,2
[rows,cols] 获得矩阵为:
[0,0],[0,2]
[3,0],[3,2]
'''
print '这个数组的每个角处的元素是:'
print y
# 输出如下:
我们的数组是:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
这个数组的每个角处的元素是:
[[ 0 2]
[ 9 11]]
返回的结果是包含每个角元素的ndarray对象。
高级和基本索引可以通过使用切片:或省略号…与索引数组组合。 以下示例使用slice作为列索引和高级索引。 当切片用于两者时,结果是相同的。 但高级索引会导致复制,并且可能有不同的内存布局。
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]]) # 二维数组
print '我们的数组是:'
print x
print '\n'
# 切片
z = x[1:4,1:3] # 切片 写法
print '切片之后,我们的数组变为:'
print z
print '\n'
# 对列使用高级索引
y = x[1:4,[1,2]] # 高级索引 写法
print '对列使用高级索引来切片:'
print y
# 输出如下:
我们的数组是:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
切片之后,我们的数组变为:
[[ 4 5]
[ 7 8]
[10 11]]
对列使用高级索引来切片:
[[ 4 5]
[ 7 8]
[10 11]]
笔记:
切片和高级索引的区别:
切片是连续的,而高级索引可以不是连续的。因此,高级所以更灵活。
切片和高级索引的相同点:
切片可以获得一维数组,也可以切片多维数组。
高级索引同样可以获得一维数组,也可以获得多维数组。
当结果对象是布尔运算(例如比较运算符)的结果时,将使用此类型的高级索引。
这个例子中,大于 5 的元素会作为布尔索引的结果返回。
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print '我们的数组是:'
print x
print '\n'
# 现在我们会打印出大于 5 的元素
print '大于 5 的元素是:'
print x[x > 5] # 布尔索引 一维布尔索引,比如:[x > 5]
#输出如下:
我们的数组是:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
大于 5 的元素是:
[ 6 7 8 9 10 11]
这个例子使用了~(取补运算符)来过滤NaN。
笔记:nan(NAN,Nan): not a number 表示不是一个数字,np.nan是一个float类型的数据
import numpy as np
a = np.array([np.nan, 1, 2, np.nan, 3,4,5]) # 笔记:array的参数[np.nan, 1, 2, np.nan, 3,4,5]是一个列表,由2个非数字(np.nan)和5个数字组成
print a[~np.isnan(a)] # 笔记:np.isnan(a) 判断是否为非数字,~np.isnan(a)表示是否为数字
# 输出如下:
[ 1. 2. 3. 4. 5.]
以下示例显示如何从数组中过滤掉非复数元素。
import numpy as np
a = np.array([1, 2+6j, 5, 3.5+5j])
print a[np.iscomplex(a)]
#输出如下:
[2.0+6.j 3.5+5.j]
术语广播是指 NumPy 在算术运算期间处理不同形状的数组的能力。 对数组的算术运算通常在相应的元素上进行。 如果两个阵列具有完全相同的形状,则这些操作被无缝执行。
笔记:广播 是 对不同形状的数组(shape)进行数值计算的方式,对数组的算术运算通常在响应的元素上进行。
import numpy as np
a = np.array([1,2,3,4])
b = np.array([10,20,30,40])
c = a * b
print c
# 输出如下:
[10 40 90 160]
形状相同
如果两个数组a和b形状相同,即:a.shape() == b.shape(),那么a+b的结果就是a与b数组对应位元素相加。要求,维度相同,且对应维度的长度相同。
形状不同
如果两个数组的维数不相同,则元素到元素的操作是不可能的。 然而,在 NumPy 中仍然可以对形状不相似的数组进行操作,因为它拥有广播功能。
较小的数组会广播到较大数组的大小,以便使它们的形状可兼容。
如果满足以下规则,可以进行广播:
如果上述规则产生有效结果,并且满足以下条件之一,那么数组被称为可广播的。
笔记:ndim中的dim是英文dimension维度的缩写。ndim是数组轴(维度)的个数。
下面的例称展示了广播的示例。
import numpy as np
a = np.array([[0.0,0.0,0.0],[10.0,10.0,10.0],[20.0,20.0,20.0],[30.0,30.0,30.0]])
b = np.array([1.0,2.0,3.0])
print '第一个数组:'
print a
print '\n'
print '第二个数组:'
print b
print '\n'
print '第一个数组加第二个数组:'
print a + b
# 输出如下:
第一个数组:
[[ 0. 0. 0.]
[ 10. 10. 10.]
[ 20. 20. 20.]
[ 30. 30. 30.]]
第二个数组:
[ 1. 2. 3.]
第一个数组加第二个数组:
[[ 1. 2. 3.]
[ 11. 12. 13.]
[ 21. 22. 23.]
[ 31. 32. 33.]]
下面的图片展示了数组b如何通过广播来与数组a兼容。
NumPy 包包含一个迭代器对象numpy.nditer。 它是一个有效的多维迭代器对象,可以用于在数组上进行迭代。 数组的每个元素可使用 Python 的标准Iterator接口来访问。
让我们使用arange()函数创建一个 3X4 数组,并使用nditer对它进行迭代。
import numpy as np
a = np.arange(0,60,5) # 0 至 59 步长5
a = a.reshape(3,4) # 也可以利用属性 a.shape(3,4)
print '原始数组是:'
print a print '\n'
print '修改后的数组是:'
for x in np.nditer(a): # x 为numpy.nditer迭代器对象
print x,
# 输出如下:
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
修改后的数组是:
0 5 10 15 20 25 30 35 40 45 50 55
迭代的顺序匹配数组的内容布局,而不考虑特定的排序(参照下例理解,转换后,迭代器输出不变)。 这可以通过迭代上述数组的转置来看到。
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print '原始数组是:'
print a
print '\n'
print '原始数组的转置是:'
b = a.T # 矩阵的置换 可以理解为以00,nn连线为轴的镜像操作
print b
print '\n'
print '修改后的数组是:'
for x in np.nditer(b): # 笔记:转换后,迭代器输出不变。
print x,
输出如下:
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
原始数组的转置是:
[[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]]
修改后的数组是:
0 5 10 15 20 25 30 35 40 45 50 55
笔记: b = a.T 其中a.T为 转置变换。元素[0,0]、元素[m,n]保持不变,其他元素行列颠倒。
如果相同元素使用 F 风格顺序存储,则迭代器选择以更有效的方式对数组进行迭代。
笔记: 所谓风格,即order参数; C(按行)、F(按列)或A(任意,默认);order的风格 影响 迭代器的输出顺序
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print '原始数组是:'
print a
print '\n'
print '原始数组的转置是:'
b = a.T
print b
print '\n'
print '以 C 风格顺序排序:'
c = b.copy(order='C')
print c for x in np.nditer(c):
print x,
print '\n'
print '以 F 风格顺序排序:'
c = b.copy(order='F')
print c
for x in np.nditer(c): # order 分隔影响 迭代器的顺序
print x,
# 输出如下:
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
原始数组的转置是:
[[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]]
以 C 风格顺序排序: # C风格:按行排序
[[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]]
0 20 40 5 25 45 10 30 50 15 35 55
以 F 风格顺序排序: # F风格:按列排序
[[ 0 20 40]
[ 5 25 45]
[10 30 50]
[15 35 55]]
0 5 10 15 20 25 30 35 40 45 50 55
可以通过显式提醒,来强制nditer对象使用某种顺序:
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print '原始数组是:'
print a
print '\n'
print '以 C 风格顺序排序:'
for x in np.nditer(a, order = 'C'): # 强制规定迭代器风格 C-行
print x,
print '\n'
print '以 F 风格顺序排序:'
for x in np.nditer(a, order = 'F'):
print x,
# 输出如下:
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
以 C 风格顺序排序:
0 5 10 15 20 25 30 35 40 45 50 55
以 F 风格顺序排序:
0 20 40 5 25 45 10 30 50 15 35 55
nditer对象有另一个可选参数op_flags。 其默认值为只读,但可以设置为读写或只写模式。 这将允许使用此迭代器修改数组元素。
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print '原始数组是:'
print a
print '\n'
for x in np.nditer(a, op_flags=['readwrite']): # 修改迭代器为 读写
x[...]=2*x # 笔记:x[...] 这个写法没有理解??
print '修改后的数组是:'
print a
# 输出如下:
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
修改后的数组是:
[[ 0 10 20 30]
[ 40 50 60 70]
[ 80 90 100 110]]
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:' )
print (a)
print ('\n' )
b = a.T # 颠倒
for x in np.nditer(a, op_flags=['readwrite']): # 修改迭代器为 读写
x[...]=2*x
print ('修改后的数组是:' )
print (a)
print("b = ")
print(b)
#输出结果
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
修改后的数组是:
[[ 0 10 20 30]
[ 40 50 60 70]
[ 80 90 100 110]]
b =
[[ 0 40 80]
[ 10 50 90]
[ 20 60 100]
[ 30 70 110]]
笔记:b = a.T 位于修改a数组值之前,但是输出b时,b的元素值也被改变了。这说明,b = a.T 并没有 创建新的数组,而是执行了a所开辟的内存,只是显示顺序改变了而已。
nditer类的构造器拥有flags参数,它可以接受下列值:
在下面的示例中,迭代器遍历对应于每列的一维数组。
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print '原始数组是:'
print a
print '\n'
print '修改后的数组是:'
for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print x,
# 输出如下:
原始数组是:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
修改后的数组是:
[ 0 20 40] [ 5 25 45] [10 30 50] [15 35 55] # 给出的值是具有**多个值的一维数组**,而不是零维数组
如果两个数组是可广播的(笔记:数组间的加减乘除运算),nditer组合对象能够同时迭代它们。 假设数组a具有维度 3X4,并且存在维度为 1X4 的另一个数组b,则使用以下类型的迭代器(数组b被广播到a的大小)。
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print '第一个数组:'
print a
print '\n'
print '第二个数组:'
b = np.array([1, 2, 3, 4], dtype = int)
print b
print '\n'
print '修改后的数组是:'
for x,y in np.nditer([a,b]): # 迭代器广播
print "%d:%d" % (x,y),
# 输出如下:
第一个数组:
[[ 0 5 10 15]
[20 25 30 35]
[40 45 50 55]]
第二个数组:
[1 2 3 4]
修改后的数组是:
0:1 5:2 10:3 15:4 20:1 25:2 30:3 35:4 40:1 45:2 50:3 55:4
NumPy包中有几个例程用于处理ndarray对象中的元素。 它们可以分为以下类型:
这个函数在不改变数据的条件下修改形状,它接受如下参数:
numpy.reshape(arr, newshape, order')
其中:
import numpy as np
a = np.arange(8)
print '原始数组:'
print a
print '\n'
b = a.reshape(4,2) # 可以用 a.reshape(4,2) 也可以用numpy.reshape()函数的形式
print '修改后的数组:'
print b
# 输出如下:
原始数组:
[0 1 2 3 4 5 6 7]
修改后的数组:
[[0 1]
[2 3]
[4 5]
[6 7]]
该函数返回数组上的一维迭代器,行为类似 Python 内建的迭代器。
笔记:不管数组的形状(例如:reshape(2,4)),只将数组作为一维进行迭代。注意,flat()方法属于ndarray类。flat 水平的
import numpy as np
a = np.arange(8).reshape(2,4) # 也是一种写法
print '原始数组:'
print a
print '\n'
print '调用 flat 函数之后:'
# 返回展开数组中的下标的对应元素
print a.flat[5] # 不管数组的形状,只将数组作为一维进行迭代。
# 输出如下:
原始数组:
[[0 1 2 3]
[4 5 6 7]]
调用 flat 函数之后:
5
该函数返回折叠为一维的数组副本,函数接受下列参数:
ndarray.flatten(order)
其中:
order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。
import numpy as np
a = np.arange(8).reshape(2,4)
print('src list')
print (a)
print ('\n')
# default is column-major
print('展开的数组:')
b = a.flatten()
print(b)
print('\n')
print('again src list')
a[0] = 23
print (a)
print ('\n')
print('展开的数组:')
print(b)
# 输出如下:
src list
[[0 1 2 3]
[4 5 6 7]]
展开的数组:
[0 1 2 3 4 5 6 7]
again src list
[[23 23 23 23]
[ 4 5 6 7]]
展开的数组:
[0 1 2 3 4 5 6 7]
笔记:从上例可以看出,副本即一个全新内存块。
这个函数返回展开的一维数组,并且按需生成副本(笔记:一个全新的内存块)。返回的数组和输入数组拥有相同数据类型。这个函数接受两个参数。
numpy.ravel(a, order)
构造器接受下列参数:
a: ndarray数组对象
order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。
import numpy as np
a = np.arange(8).reshape(2,4)
print '原数组:'
print a
print '\n'
print '调用 ravel 函数之后:'
print a.ravel()
print '\n'
print '以 F 风格顺序调用 ravel 函数之后:'
print a.ravel(order = 'F')
原数组:
[[0 1 2 3]
[4 5 6 7]]
调用 ravel 函数之后:
[0 1 2 3 4 5 6 7]
以 F 风格顺序调用 ravel 函数之后:
[0 4 1 5 2 6 3 7]
这个函数翻转给定数组的维度。如果可能的话它会返回一个视图。函数接受下列参数:
笔记:行、列对调 形成的翻转
numpy.transpose(arr, axes)
其中:
import numpy as np
a = np.arange(12).reshape(3,4)
print '原数组:'
print a
print '\n'
print '转置数组:'
print np.transpose(a)
#输出如下:
原数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
转置数组:
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
该函数属于ndarray类,行为类似于numpy.transpose。
笔记:写的时候由于没有参数,因此T不需要加括号
import numpy as np
a = np.arange(12).reshape(3,4)
print '原数组:'
print a
print '\n'
print '转置数组:'
print a.T # 写法简单,但是没有numpy.transpose灵活。
# 输出如下:
原数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
转置数组:
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
笔记:这种置换,可以理解为在原有一维数组的基础上,调整order属性。即:原ndarray对象.order=‘C’, 调用numpy.ndarray.T 方法 或者 numpy.transpose()后,ndarray对象.order=‘F’。反之亦然。
该函数向后滚动特定的轴,直到一个特定位置。这个函数接受三个参数:
numpy.rollaxis(arr, axis, start)
其中:
笔记:
轴的介绍
例如 a = np.arange(12).reshape(1,2,3)
1表示第一维长度1,第一维即:轴0
2表示第二维长度2,第二维即:轴1
3表示第三维长度3,第三维即:轴2
轴也有如下表示
轴0 深度方向
轴1 高度方向
轴2 宽度方向
轴的滚动
二维滚动
a=np.arrage(12).reshape(3,4)
a.shape = (3,4)
b=np.rollaxis(a,1) # 滚动轴
b.shape = (4,3)
import numpy as np
a = np.arange(24).reshape(2,3,4)
print("a=", a)
print("a.shape = ", a.shape)
print("\n")
d = np.rollaxis(a,1)
print("np.rollaxis(a,1) = \n", d)
print("shap = ", d.shape)
print("\n")
b = np.rollaxis(a,2)
print("np.rollaxis(a,2) = \n", b)
print("shap = ", b.shape)
print("\n")
c = np.rollaxis(a,2,1)
print("np.rollaxis(a,2,1) = \n", c)
print("shap = ", c.shape)
# 输出如下:
a= [[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
a.shape = (2, 3, 4)
np.rollaxis(a,1) =
[[[ 0 1 2 3]
[12 13 14 15]]
[[ 4 5 6 7]
[16 17 18 19]]
[[ 8 9 10 11]
[20 21 22 23]]]
shap = (3, 2, 4) # 轴1 和 轴0 滚动调换
np.rollaxis(a,2) =
[[[ 0 4 8]
[12 16 20]]
[[ 1 5 9]
[13 17 21]]
[[ 2 6 10]
[14 18 22]]
[[ 3 7 11]
[15 19 23]]]
shap = (4, 2, 3) # 轴2 和轴1 滚动对调
np.rollaxis(a,2,1) =
[[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
[[12 16 20]
[13 17 21]
[14 18 22]
[15 19 23]]]
shap = (2, 4, 3) # 轴2 和 轴1 滚动对调
该函数交换数组的两个轴。对于 1.10 之前的 NumPy 版本,会返回交换后数组的试图。这个函数接受下列参数:
numpy.swapaxes(arr, axis1, axis2)
# 创建了三维的 ndarray
import numpy as np
a = np.arange(8).reshape(2,2,2)
print '原数组:'
print a
print '\n'
# 现在交换轴 0(深度方向)到轴 2(宽度方向)
print '调用 swapaxes 函数后的数组:'
print np.swapaxes(a, 2, 0)
# 输出如下:
原数组:
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
调用 swapaxes 函数后的数组:
[[[0 4]
[2 6]]
[[1 5]
[3 7]]]
笔记:区分修改形状和修改维度。
修改形状是在相同维度下修改形状,例如:a.shape() = (2,3) 修改形状后 a.shape() = (1,6) 。
修改维度则是增加或减少维度。例如:2维 变 3
如前所述,NumPy 已经内置了对广播的支持。 此功能模仿广播机制。 它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。
笔记:b = np.broadcast(x,y) x为维度形状模板,将y广播与x形状相同。返回值b 并不是一个ndarray对象,而是一个封装将一个数组广播到另一个数组的结果。比如: b =
b内包含有x和广播y的结果, 例如:r,c = b.iters r迭代器表示x,c迭代器表示y
该函数使用两个数组作为输入参数。 下面的例子说明了它的用法。
import numpy as np
x = np.array([[1], [2], [3]]) # 二维数组
y = np.array([4, 5, 6]) # 一维数组
# 对 y 广播 x
b = np.broadcast(x,y)
# 它拥有 iterator 属性,基于自身组件的迭代器元组
print '对 y 广播 x:'
r,c = b.iters
print next(r), next(c)
print next(r), c.next(c)
print '\n'
# shape 属性返回广播对象的形状
print '广播对象的形状:'
print b.shape
print '\n'
# 手动使用 broadcast 将 x 与 y 相加
b = np.broadcast(x,y)
c = np.empty(b.shape)
print '手动使用 broadcast 将 x 与 y 相加:'
print c.shape
print '\n'
c.flat = [u + v for (u,v) in b] # flat 该函数返回数组上的**一维迭代器**,行为类似 Python 内建的迭代器。
print '调用 flat 函数:'
print c
print '\n'
# 获得了和 NumPy 内建的广播支持相同的结果
print 'x 与 y 的和:'
print x + y
# 输出如下:
对 y 广播 x:
1 4
1 5
广播对象的形状:
(3, 3)
手动使用 broadcast 将 x 与 y 相加:
(3, 3)
调用 flat 函数:
[[ 5. 6. 7.]
[ 6. 7. 8.]
[ 7. 8. 9.]]
x 与 y 的和:
[[5 6 7]
[6 7 8]
[7 8 9]]
此函数将数组广播到新形状。 它在原始数组上返回只读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError。
注意 - 此功能可用于 1.10.0 及以后的版本。
该函数接受以下参数。
numpy.broadcast_to(array, shape, subok)
import numpy as np
a = np.arange(4).reshape(1,4)
print '原数组:'
print a
print '\n'
print '调用 broadcast_to 函数之后:'
print np.broadcast_to(a,(4,4))
# 输出如下:
[[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]
函数通过在指定位置插入新的轴来扩展数组形状。该函数需要两个参数:
numpy.expand_dims(arr, axis) # axis 轴
其中:
import numpy as np
x = np.array(([1,2],[3,4]))
print '数组 x:'
print x
print '\n'
y = np.expand_dims(x, axis = 0)
print '数组 y:'
print y
print '\n'
print '数组 x 和 y 的形状:'
print x.shape, y.shape
print '\n'
# 在位置 1 插入轴
y = np.expand_dims(x, axis = 1)
print '在位置 1 插入轴之后的数组 y:'
print y
print '\n'
print 'x.ndim 和 y.ndim:'
print x.ndim,y.ndim
print '\n'
print 'x.shape 和 y.shape:'
print x.shape, y.shape
输出如下:
数组 x:
[[1 2]
[3 4]]
数组 y:
[[[1 2]
[3 4]]]
数组 x 和 y 的形状:
(2, 2) (1, 2, 2)
在位置 1 插入轴之后的数组 y:
[[[1 2]]
[[3 4]]]
x.ndim 和 y.ndim:
2 3
x.shape and y.shape:
(2, 2) (2, 1, 2)
函数从给定数组的形状中删除一维条目。 此函数需要两个参数。
numpy.squeeze(arr, axis)
其中:
import numpy as np
x = np.arange(9).reshape(1,3,3)
print '数组 x:'
print x
print '\n'
y = np.squeeze(x)
print '数组 y:'
print y
print '\n'
print '数组 x 和 y 的形状:'
print x.shape, y.shape
输出如下:
数组 x:
[[[0 1 2]
[3 4 5]
[6 7 8]]]
数组 y:
[[0 1 2]
[3 4 5]
[6 7 8]]
数组 x 和 y 的形状:
(1, 3, 3) (3, 3)
此函数用于沿指定轴连接相同形状的两个或多个数组。 该函数接受以下参数。
笔记:连接的前提形状相同。
numpy.concatenate((a1, a2, ...), axis)
其中:
import numpy as np
a = np.array([[1,2],[3,4]]) # 一行两列
print '第一个数组:'
print a
print '\n'
b = np.array([[5,6],[7,8]]) # 一行两列
print '第二个数组:'
print b
print '\n'
# 两个数组的维度相同
print '沿轴 0 连接两个数组:'
print np.concatenate((a,b)) # 轴0 一行
print '\n'
print '沿轴 1 连接两个数组:'
print np.concatenate((a,b),axis = 1) # 轴1 列
输出如下:
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
沿轴 0 连接两个数组:
[[1 2]
[3 4]
[5 6]
[7 8]]
沿轴 1 连接两个数组:
[[1 2 5 6]
[3 4 7 8]]
此函数沿新轴连接数组序列。 此功能添加自 NumPy 版本 1.10.0。 需要提供以下参数。
numpy.stack(arrays, axis)
其中:
import numpy as np
a = np.array([[1,2],[3,4]])
print '第一个数组:'
print a
print '\n'
b = np.array([[5,6],[7,8]])
print '第二个数组:'
print b
print '\n'
print '沿轴 0 堆叠两个数组:'
print np.stack((a,b),0)
print '\n'
print '沿轴 1 堆叠两个数组:'
print np.stack((a,b),1)
# 输出如下:
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
沿轴 0 堆叠两个数组:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
沿轴 1 堆叠两个数组:
[[[1 2]
[5 6]]
[[3 4]
[7 8]]]
numpy.stack函数的变体,通过堆叠来生成水平的单个数组。
import numpy as np
a = np.array([[1,2],[3,4]])
print '第一个数组:'
print a
print '\n'
b = np.array([[5,6],[7,8]])
print '第二个数组:'
print b
print '\n'
print '水平堆叠:'
c = np.hstack((a,b))
print c
print '\n'
输出如下:
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
水平堆叠:
[[1 2 5 6]
[3 4 7 8]]
numpy.stack函数的变体,通过堆叠来生成竖直的单个数组。
import numpy as np
a = np.array([[1,2],[3,4]])
print '第一个数组:'
print a
print '\n'
b = np.array([[5,6],[7,8]])
print '第二个数组:'
print b
print '\n'
print '竖直堆叠:'
c = np.vstack((a,b))
print c
输出如下:
第一个数组:
[[1 2]
[3 4]]
第二个数组:
[[5 6]
[7 8]]
竖直堆叠:
[[1 2]
[3 4]
[5 6]
[7 8]]
该函数沿特定的轴将数组分割为子数组。函数接受三个参数:
numpy.split(ary, indices_or_sections, axis)
其中:
import numpy as np
a = np.arange(9)
print ("a = \n", a)
b = np.split(a,3)
print ('np.split(a,3) = \n',b)
b = np.split(a,[4,7])
print("np.split(a,[4,7]) = \n", b)
# 输出如下:
a =
[0 1 2 3 4 5 6 7 8]
np.split(a,3) =
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
np.split(a,[4,7]) =
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
numpy.hsplit是split()函数的特例,其中轴为 1 表示水平分割,无论输入数组的维度是什么。
import numpy as np
a = np.arange(16).reshape(4,4)
print '第一个数组:'
print a
print '\n'
print '水平分割:'
b = np.hsplit(a,2)
print b
print '\n'
#输出:
第一个数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
水平分割:
[array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]]),
array([[ 2, 3],
[ 6, 7],
[10, 11],
[14, 15]])]
numpy.vsplit是split()函数的特例,其中轴为 0 表示竖直分割,无论输入数组的维度是什么。下面的例子使之更清楚。
import numpy as np
a = np.arange(16).reshape(4,4)
print '第一个数组:'
print a
print '\n'
print '竖直分割:'
b = np.vsplit(a,2)
print b
输出如下:
第一个数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
竖直分割:
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]
此函数返回指定大小的新数组。 如果新大小大于原始大小,则包含原始数组中的元素的重复副本。 该函数接受以下参数。
笔记:np.resize() 与 ndarray.shape() 效果相同
numpy.resize(arr, shape)
其中:
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print '第一个数组:'
print a
print '\n'
print '第一个数组的形状:'
print a.shape
print '\n'
b = np.resize(a, (3,2))
print '第二个数组:'
print b
print '\n'
print '第二个数组的形状:'
print b.shape
print '\n'
# 要注意 a 的第一行在 b 中重复出现,因为尺寸变大了
print '修改第二个数组的大小:'
b = np.resize(a,(3,3))
print b
输出如下:
第一个数组:
[[1 2 3]
[4 5 6]]
第一个数组的形状:
(2, 3)
第二个数组:
[[1 2]
[3 4]
[5 6]]
第二个数组的形状:
(3, 2)
修改第二个数组的大小:
[[1 2 3]
[4 5 6]
[1 2 3]]
此函数在输入数组的末尾添加值。 附加操作不是原地的,而是分配新的数组。 此外,输入数组的维度必须匹配否则将生成ValueError。
笔记:np.append() 返回 新的数组(分配新的内存)
函数接受下列函数:
numpy.append(arr, values, axis)
其中:
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print '第一个数组:'
print a
print '\n'
print '向数组添加元素:'
print np.append(a, [7,8,9])
print '\n'
print '沿轴 0 添加元素:'
print np.append(a, [[7,8,9]],axis = 0)
print '\n'
print '沿轴 1 添加元素:'
print np.append(a, [[5,5,5],[7,8,9]],axis = 1)
#输出如下:
第一个数组:
[[1 2 3]
[4 5 6]]
向数组添加元素:
[1 2 3 4 5 6 7 8 9]
沿轴 0 添加元素:
[[1 2 3]
[4 5 6]
[7 8 9]]
沿轴 1 添加元素:
[[1 2 3 5 5 5]
[4 5 6 7 8 9]]
此函数在给定索引之前,沿给定轴在输入数组中插入值。 如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。
insert()函数接受以下参数:
numpy.insert(arr, obj, values, axis)
其中:
import numpy as np
a = np.array([[1,2],[3,4],[5,6]])
print ('第一个数组:' )
print (a )
print ('未传递 Axis 参数。 在插入之前输入数组会被展开。' )
print (np.insert(a,3,[11,12]) )
print ('\n' )
print ('传递了 Axis 参数。 会广播值数组来配输入数组。' )
print ('沿轴 0 广播:')
print (np.insert(a,1,[11],axis = 0) )
print ('\n' )
print ('沿轴 1 广播:' )
print (np.insert(a,1,11,axis = 1))
# 输出结果
第一个数组:
[[1 2]
[3 4]
[5 6]]
未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 1 2 3 11 12 4 5 6]
传递了 Axis 参数。 会广播值数组来配输入数组。
沿轴 0 广播:
[[ 1 2]
[11 11]
[ 3 4]
[ 5 6]]
沿轴 1 广播:
[[ 1 11 2]
[ 3 11 4]
[ 5 11 6]]
此函数返回从输入数组中删除指定子数组的新数组。 与insert()函数的情况一样,如果未提供轴参数,则输入数组将展开。 该函数接受以下参数:
Numpy.delete(arr, obj, axis)
其中:
import numpy as np
a = np.arange(12).reshape(3,4)
print '第一个数组:'
print a
print '\n'
print '未传递 Axis 参数。 在插入之前输入数组会被展开。'
print np.delete(a,5)
print '\n'
print '删除第二列:'
print np.delete(a,1,axis = 1)
print '\n'
print '包含从数组中删除的替代值的切片:'
a = np.array([1,2,3,4,5,6,7,8,9,10])
print np.delete(a, np.s_[::2]) # [::2] 表示 [start:end:step]
#输出如下:
第一个数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 0 1 2 3 4 6 7 8 9 10 11]
删除第二列:
[[ 0 2 3]
[ 4 6 7]
[ 8 10 11]]
包含从数组中删除的替代值的切片:
[ 2 4 6 8 10]
此函数返回输入数组中的去重元素数组。 该函数能够返回一个元组,包含去重数组和相关索引的数组。 索引的性质取决于函数调用中返回参数的类型。
笔记:去掉重复元素,并且返回去重数组会排序
numpy.unique(arr, return_index, return_inverse, return_counts)
其中:
import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])
print '第一个数组:'
print a
print '\n'
print '第一个数组的去重值:'
u = np.unique(a) # 会排序
print u
print '\n'
print '去重数组的索引数组:'
u,indices = np.unique(a, return_index = True)
print indices
print '\n'
print '我们可以看到每个和原数组下标对应的数值:'
print a
print '\n'
print '去重数组的下标:'
u,indices = np.unique(a,return_inverse = True)
print u
print '\n'
print '下标为:'
print indices
print '\n'
print '使用下标重构原数组:'
print u[indices]
print '\n'
print '返回去重元素的重复数量:'
u,indices = np.unique(a,return_counts = True)
print u
print indices
输出如下:
第一个数组:
[5 2 6 2 7 5 6 8 2 9]
第一个数组的去重值:
[2 5 6 7 8 9]
去重数组的索引数组:
[1 0 2 4 7 9]
我们可以看到每个和原数组下标对应的数值:
[5 2 6 2 7 5 6 8 2 9]
去重数组的下标:
[2 5 6 7 8 9]
下标为:
[1 0 2 0 3 1 2 4 0 5]
使用下标重构原数组:
[5 2 6 2 7 5 6 8 2 9]
返回唯一元素的重复数量:
[2 5 6 7 8 9]
[3 2 2 1 1 1]