NumPy是Python语言的一个扩充程序库。支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。Numpy内部解除了Python的GIL(全局解释器锁),运行效率极好,是大量机器学习框架的基础库!
关于GIL请参考博客:http://www.cnblogs.com/wj-1314/p/9056555.html
NumPy的全名为Numeric Python,是一个开源的Python科学计算库,它包括:
一个强大的N维数组对象ndrray;
比较成熟的(广播)函数库;
用于整合C/C++和Fortran代码的工具包;
实用的线性代数、傅里叶变换和随机数生成函数
1.1 NumPy的优点:
对于同样的数值计算任务,使用NumPy要比直接编写Python代码便捷得多;
NumPy中的数组的存储效率和输入输出性能均远远优于Python中等价的基本数据结构,且其能够提升的性能是与数组中的元素成比例的;
NumPy的大部分代码都是用C语言写的,其底层算法在设计时就有着优异的性能,这使得NumPy比纯Python代码高效得多
当然,NumPy也有其不足之处,由于NumPy使用内存映射文件以达到最优的数据读写性能,而内存的大小限制了其对TB级大文件的处理;此外,NumPy数组的通用性不及Python提供的list容器。因此,在科学计算之外的领域,NumPy的优势也就不那么明显。
二、数组ndarray
NumPy最重要的一个特点就是其N维数组对象(即ndarray),该对象是一个快速而灵活的大数据集容器,该对象由两部分组成:
实际的数据;
描述这些数据的元数据;
Numpy中定义的最重要的对象是成为ndarray的N维数组类型。它描述相同类型的元素集合。可以使用基于零的索引访问集合中的项目。
ndarray中的每个元素在内存中使用相同大小的块。ndarray中每个元素是数据类型对象的对象(称为dtype)
大部分的数组操作仅仅是修改元数据部分,而不改变其底层的实际数据。数组的维数称为秩,简单来说就是如果你需要获取数组中一个特定元素所需的坐标数,如a是一个2×3×4的矩阵,你索引其中的一个元素必须给定三个坐标a[x,y,z],故它的维数就是3。而轴可以理解为一种对数组空间的分割,以数组a为例,如果我们以0为轴,那么a可以看成是一个由两个元素构成的数组,其中每个元素都是一个3×4的数组。
我们可以直接将数组看作一种新的数据类型,就像list、tuple、dict一样,但数组中所有元素的类型必须是一致的,Python支持的数据类型有整型、浮点型以及复数型,但这些类型不足以满足科学计算的需求,因此NumPy中添加了许多其他的数据类型,如bool、inti、int64、float32、complex64等。同时,它也有许多其特有的属性和方法。
官方解释:
+ View Code
2.1 常用ndarray属性:
dtype 描述数组元素的类型
shape 以tuple表示的数组形状
ndim 数组的维度
size 数组中元素的个数
itemsize 数组中的元素在内存所占字节数
T 数组的转置
flat 返回一个数组的迭代器,对flat赋值将导致整个数组的元素被覆盖
real/imag 给出复数数组的实部/虚部
import numpy as np
# 创建简单的列表
a = [1,2,3,4,5,6]
# 讲列表转换为数组
b = np.array(a)
# Numpy查看数组属性
print(b.size)
#6
# 数组形状
print(b.shape)
# (6,)
# 数组维度
print(b.ndim)
# 1
# 数组元素类型
print(b.dtype)
# int32
import numpy as np
a = np.array([1,2,3])
print(a)
# [1 2 3]
# 多于一个维度
a = np.array([[1, 2], [3, 4]])
print(a)
# [[1 2]
# [3 4]]
# 最小维度
a = np.array([1, 2, 3,4,5], ndmin = 2)
print(a)
# [[1 2 3 4 5]]
# dtype 参数
a = np.array([1, 2, 3], dtype = complex)
print(a)
# [1.+0.j 2.+0.j 3.+0.j]
ndarray 对象由计算机内存中的一维连续区域组成,带有将每个元素映射到内存块中某个位置的索引方案。 内存块以按行(C 风格)或按列(FORTRAN 或 MatLab 风格)的方式保存元素。
2.2 常用ndarray方法:
reshape(…) 返回一个给定shape的数组的副本
resize(…) 返回给定shape的数组,原数组shape发生改变
flatten()/ravel() 返回展平数组,原数组不改变
astype(dtype) 返回指定元素类型的数组副本
fill() 将数组元素全部设定为一个标量值
sum/Prod() 计算所有数组元素的和/积
mean()/var()/std() 返回数组元素的均值/方差/标准差
max()/min()/ptp()/median() 返回数组元素的最大值/最小值/取值范围/中位数
argmax()/argmin() 返回最大值/最小值的索引
sort() 对数组进行排序,axis指定排序的轴;kind指定排序算法,默认是快速排序
view()/copy() view创造一个新的数组对象指向同一数据;copy是深复制
tolist() 将数组完全转为列表,注意与直接使用list(array)的区别
compress() 返回满足条件的元素构成的数组
numpy.reshape:
import numpy as np
a = np.arange(8)
print('原始数组:')
print(a)
print('\n')
b = a.reshape(4,2)
print('修改后的数组:')
print(b)
'''结果
原始数组:
[0 1 2 3 4 5 6 7]
修改后的数组:
[[0 1]
[2 3]
[4 5]
[6 7]]
'''
numpy.ndarray.flatten:
import numpy as np
a = np.arange(8).reshape(2,4)
print('原数组:')
print(a)
print('\n')
# default is column-major
print('展开的数组:')
print(a.flatten())
print('\n')
print('以 F 风格顺序展开的数组:')
print(a.flatten(order = 'F'))
'''结果:
原数组:
[[0 1 2 3]
[4 5 6 7]]
展开的数组:
[0 1 2 3 4 5 6 7]
以 F 风格顺序展开的数组:
[0 4 1 5 2 6 3 7]
'''
numpy.ravel:
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]'''
2.3 数组的创建
numpy中使用array()函数创建数组,array的首个参数一定是一个序列,可以是元组也可以是列表。
2.3.1 一维数组的创建
可以使用numpy中的arange()函数创建一维有序数组,它是内置函数range的扩展版。
In [1]: import numpy as np
In [2]: ls1 = range(www.dfgjpt.com/ 10)
In [3]: list(ls1)
Out[3]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [4]: type(ls1)
Out[4]: range
In [5]: ls2 = np.arange(10)
In [6]: list(ls2)
Out[6]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [7]: type(ls2)
Out[7]: numpy.ndarray
通过arange生成的序列就不是简简单单的列表类型了,而是一个一维数组。
如果一维数组不是一个规律的有序元素,而是人为的输入,就需要array()函数创建了。
In [8]: arr1 = np.array((1,20,13,28,22))
In [9]: arr1
Out[9]: array([ 1, 20, 13, 28, 22])
In [10]: type(arr1)
Out[10]: numpy.ndarray
上面是由元组序列构成的一维数组。
In [11]: arr2 = np.array([1,1,2,3,5,8,13,21])
In [12]: arr2
Out[12]: array([ 1, 1, 2, 3, 5, 8, 13, 21])
In [13]: type(arr2)
Out[13]: numpy.ndarray
上面是由列表序列构成的一维数组。
2.3.2 二维数组的创建
二维数组的创建,其实在就是列表套列表或元组套元组。
In [14]: arr3 = np.array(((1,1,2,3),(5,8,13,21),(34,55,89,144)))
In [15]: arr3
Out[15]:
array([[ 1, 1, 2, 3],
[ 5, 8, 13, 21],
[ 34, 55, 89, 144]])
上面使用元组套元组的方式。
In [16]: arr4 = np.array(www.yongshiyule178.com [[1,2,3,4],[5,6,7,8],[9,10,11,12]])
In [17]: arr4
Out[17]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
上面使用列表套列表的方式。
对于高维数组在将来的数据分析中用的比较少,这里关于高维数组的创建就不赘述了,构建方法仍然是套的方式。
上面所介绍的都是人为设定的一维、二维或高维数组,numpy中也提供了几种特殊的数组,它们是:
In [18]: np.ones(3) #返回一维元素全为1的数组
Out[18]: array([ 1., 1., 1.])
In [19]: np.ones([3,4]) #返回元素全为1的3×4二维数组
Out[19]:
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
In [20]: np.zeros(3) #返回一维元素全为0的数组
Out[20]: array([ 0., 0., 0.])
In [21]: np.zeros([3,4]) #返回元素全为0的3×4二维数组
Out[21]:
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
In [22]: np.empty(3) #返回一维空数组
Out[22]: array(www.00534.cn[ 0., 0., 0.])
In [23]: np.empty([3,4]) #返回3×4二维空数组
Out[23]:
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
2.3.3 ones函数
返回特定大小,以1填充的新数组
>>> import numpy as np
>>> a=np.ones(3);a
array([ 1., 1., 1.])
>>> b=np.ones(www.06640.cn(3,2));b
array([[ 1., 1.],
[ 1., 1.],
[ 1., 1.]])
2.3.4 zeros函数
返回特定大小,以0填充的新数组。
官方库的解释:
def zeros(shape, dtype=None, order='C'): # real signature unknown; restored from __doc__
"""
zeros(shape, dtype=float, order='C')
Return a new array of given shape and type, filled with zeros.
Parameters
----------
shape : int or tuple of ints
Shape of the new www.tianzunyule178.com array, e.g., ``(2, 3)`` or ``2``.
dtype : data-type, optional
The desired data-type for the array, e.g., `numpy.int8`. Default is
`numpy.float64`.
order : {'C', 'F'}, optional, default: 'C'
Whether to store multi-dimensional data in row-major
(C-style) or column-major (Fortran-style) order in
memory.
Returns
-------
out : ndarray
Array of zeros with the given shape, dtype, and order.
See Also
--------
zeros_like : Return an array of zeros with shape and type of input.
empty : Return a new uninitialized array.
ones : Return a new array setting values to one.
full : Return a new array of given shape filled with value.
Examples
--------
>>> np.zeros(5)
array([ 0., 0., 0., 0., 0.])
>>> np.zeros((5,), dtype=int)
array([0, 0, 0, 0, 0])
>>> np.zeros((2, 1))
array([[ 0.],
[ 0.]])
>>> s = (2,2)
>>> np.zeros(s)
array([[ 0., 0.],
[ 0., 0.]])
>>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype
array([(0, 0), (0, 0)],
dtype=[('x', '<i4'), ('y', '<i4')])
"""
pass
numpy.zeros(shape, dtype=float, order=’C’)
参数:
shape:int或ints序列
新数组的形状,例如(2,3 )或2。
dtype:数据类型,可选
数组的所需数据类型,例如numpy.int8。默认值为 numpy.float64。
order:{'C','F'},可选
是否在存储器中以C或Fortran连续(按行或列方式)存储多维数据。
返回:
1
2
out:ndarray
具有给定形状,数据类型和顺序的零数组。
>>> c=np.zeros(3)
>>> c
array([ 0., 0., 0.])
>>> d=np.zeros((2,3));d
array([[ 0., 0., 0.],
[ 0., 0., 0.]])
#d=np.zeros(2,3)会报错,d=np.zeros(3,dtype=int)来改变默认的数据类型
2.3.5 eye&identity函数
>>> e=np.eye(3);e
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
>>> e=np.eye(3,2);e
array([[ 1., 0.],
[ 0., 1.],
[ 0., 0.]])
>>> e=np.eye(3,1);e
array([[ 1.],
[ 0.],
[ 0.]])
>>> e=np.eye(3,3);e
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
>>> e=np.eye(3,3,1);e
array([[ 0., 1., 0.],
[ 0., 0., 1.],
[ 0., 0., 0.]])
e=np.eye(3,3,2);e
array([[ 0., 0., 1.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
>>> e=np.eye(3,3,3);e
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
>>> e=np.eye(3,3,4);e
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
>>> p=np.identity(4);p
array([[ 1., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 0., 1., 0.],
[ 0., 0., 0., 1.]])
>>> p=np.identity(4,3);p #会报错
>>> p=np.identity((4,3));p #会报错
2.3.6 empty函数
它创建指定形状和dtype的未初始化数组。它使用以下构造函数:
1
numpy.empty(shape, dtype = float, order = 'C')
注意:数组为随机值,因为他们未初始化。
import numpy as np
x = np.empty([3,2], dtype = int)
print(x)
# [[1762 0]
# [ 0 0]
# [ 0 0]]
>>> a=np.empty(3);a
array([ 1.60091154e-163, 1.12069303e-258, 3.23790862e-318])
>>> a=np.empty((3,3));a
array([[ 1.57741456e-284, 1.57680914e-284, 1.56735002e-163],
[ 1.56205068e-163, 1.62511438e-163, 1.21880041e+171],
[ 1.57757869e-052, 7.34292780e+223, 4.71235856e+257]])
2.3.7 ones_like zero_like empy_like函数
>>> a=np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]])
>>> a.shape
(3, 2, 2)
>>> b=np.ones_like(a)
>>> b
array([[[1, 1],
[1, 1]],
[[1, 1],
[1, 1]],
[[1, 1],
[1, 1]]])
>>> b=np.zeros_like(a);b
array([[[0, 0],
[0, 0]],
[[0, 0],
[0, 0]],
[[0, 0],
[0, 0]]])
>>> a=np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]])
>>> b=np.empty_like(a);b
array([[[39125057, 40012256],
[81313824, 81313856]],
[[ 0, 0],
[ 0, 0]],
[[ 0, 0],
[ 0, 0]]])
#注意,shape和dtype均复制
三,Numpy数据类型
NumPy 支持比 Python 更多种类的数值类型。 下表显示了 NumPy 中定义的不同标量数据类型。
序号 数据类型及描述
1. bool_存储为一个字节的布尔值(真或假)
2. int_默认整数,相当于 C 的long,通常为int32或int64
3. intc相当于 C 的int,通常为int32或int64
4. intp用于索引的整数,相当于 C 的size_t,通常为int32或int64
5. int8字节(-128 ~ 127)
6. int1616 位整数(-32768 ~ 32767)
7. int3232 位整数(-2147483648 ~ 2147483647)
8. int6464 位整数(-9223372036854775808 ~ 9223372036854775807)
9. uint88 位无符号整数(0 ~ 255)
10. uint1616 位无符号整数(0 ~ 65535)
11. uint3232 位无符号整数(0 ~ 4294967295)
12. uint6464 位无符号整数(0 ~ 18446744073709551615)
13. float_float64的简写
14. float16半精度浮点:符号位,5 位指数,10 位尾数
15. float32单精度浮点:符号位,8 位指数,23 位尾数
16. float64双精度浮点:符号位,11 位指数,52 位尾数
17. complex_complex128的简写
18. complex64复数,由两个 32 位浮点表示(实部和虚部)
19. complex128复数,由两个 64 位浮点表示(实部和虚部)
NumPy 数字类型是dtype(数据类型)对象的实例,每个对象具有唯一的特征。 这些类型可以是np.bool_,np.float32等。
3.1 数据类型对象(dtype)
数据类型对象描述了对应于数组的固定内存块的解释,取决于以下方面:
数据类型(整数、浮点或者 Python 对象)
数据大小
字节序(小端或大端)
在结构化类型的情况下,字段的名称,每个字段的数据类型,和每个字段占用的内存块部分。
如果数据类型是子序列,它的形状和数据类型。
字节顺序取决于数据类型的前缀<或>。<意味着编码是小端(最小有效字节存储在最小地址中)。>意味着编码是大端(最大有效字节存储在最小地址中)。
dtype语法构造:
1
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',以及其他。
dt = np.dtype('i4')
print(dt)
# int32
# 使用端记号
dt = np.dtype('>i4')
print(dt)
# >i4
# 首先创建结构化数据类型。
dt = np.dtype([('age',np.int8)])
print(dt)
# [('age', 'i1')]
# 现在将其应用于 ndarray 对象
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a)
# [(10,) (20,) (30,)]
# 文件名称可用于访问 age 列的内容
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a['age'])
# [10 20 30]
四,Numpy 切片和索引
ndarray对象的内容可以通过索引或切片来访问和修改,就像python的内置容器对象一样。
nadarray 对象中的元素遵循基于零的索引,有三种可用的索引方法类型:字段访问,基础切片和高级索引。
基本切片是Python中基本切片概念到n维的扩展,通过start,stop和step参数提供给内置函数的slice函数来构造一个Python slice对象,此slice对象被传递给数组来提取数组的一部分。
练习:
import numpy as np
a = np.arange(10)
print(a)
# [0 1 2 3 4 5 6 7 8 9]
s = slice(2,7,2)
print(s)
# slice(2, 7, 2)
print(a[s])
# [2 4 6]
b = a[2:7:2]
print(b)
# [2 4 6]
# 对单个元素进行切片
b = a[5]
print(b)
# 5
# 对始于索引的元素进行切片
print(a[2:])
# [2 3 4 5 6 7 8 9]
# 对索引之间的元素进行切片
print(a[2:5])
# [2 3 4]
# 二维数组
# 最开始的数组
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:])
'''
我们的数组是:
[[1 2 3]
[3 4 5]
[4 5 6]]
第二列的元素是:
[2 4 5]
第二行的元素是:
[3 4 5]
第二列及其剩余元素是:
[[2 3]
[4 5]
[5 6]]'''
五,Numpy-IO
ndarray对象可以保存到磁盘文件并从磁盘文件加载,可用的IO功能有:
load()和save() 函数处理Numpy 二进制文件(带npy扩展名)。
loadtxt() 和savetxt() 函数处理正常的文本文件。
Numpy为ndarray对象引入了一个简单的文件格式,这个npy文件在磁盘文件中,存储重建ndarray所需的数据,图形,dtype和其他信息,以便正确获取数组,即使该文件在具有不同架构的一台机器上。
numpy.save()
此函数是讲文件输入数组存储在具有npy扩展名的磁盘文件中。
1
2
3
import numpy as np
a = np.array([1,2,3,4,5])
np.save('outfile',a)
为了从outfile.npy重建数组,请使用load()函数。
1
2
3
4
import numpy as np
b = np.load('outfile.npy')
print(b)
# [1 2 3 4 5]
save()和load()函数接受一个附加的布尔参数allow_pickles。Python中的pickle用在保存到磁盘文件或者从磁盘文件读取之前,对对象进行序列化和反序列化。
savetxt()
以简单文本文件格式存储和获取数组数据,通过savetxt()和loadtxt()函数来完成的。
import numpy as np
a = np.array([1,2,3,4,5])
np.savetxt('out.txt',a)
b = np.loadtxt('out.txt')
print(b)
# [1. 2. 3. 4. 5.]
savetxt()和loadtxt()函数接受附加的可选参数,例如页首,页尾和分隔符。
六,numpy中的ndarray与array的区别、不同
答:Well, np.array is just a convenience function to create an ndarray, it is not a class itself.
(嗯,np.array只是一个便捷的函数,用来创建一个ndarray,它本身不是一个类)
You can also create an array using np.ndarray, but it is not the recommended way. From the docstring of np.ndarray:
(你也能够用np.ndarray来创建,但这不是推荐的方式。来自np.ndarray的文档:)
Python NumPy学习
最新推荐文章于 2021-02-09 20:37:11 发布