【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
一、yNumPy - 简介
NumPy是Python语言的一个扩充程序库。支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。Numpy内部解除了CPython的GIL(全局解释器锁),运行效率极好,是大量机器学习框架的基础库!
通过Numpy,可以进行如下操作:
- 数组的算数和逻辑运算。
- 傅立叶变换和用于图形操作的例程。
- 与线性代数有关的操作,NumPy 拥有线性代数和随机数生成的内置函数。
现在一般通过Numpy、Scipy(Scientific Python)和Matplotlib(绘图库)结合来替代MatLab,是一个流行的技术计算平台。
NumPy的优点:
- 对于同样的数值计算任务,使用NumPy要比直接编写Python代码便捷得多;
- NumPy中的数组的存储效率和输入输出性能均远远优于Python中等价的基本数据结构,且其能够提升的性能是与数组中的元素成比例的;
- NumPy的大部分代码都是用C语言写的,其底层算法在设计时就有着优异的性能,这使得NumPy比纯Python代码高效得多
当然,NumPy也有其不足之处,由于NumPy使用内存映射文件以达到最优的数据读写性能,而内存的大小限制了其对TB级大文件的处理;此外,NumPy数组的通用性不及Python提供的list容器。因此,在科学计算之外的领域,NumPy的优势也就不那么明显。
mat()函数和array()函数的区别
Numpy函数库中存在两种不同的数据类型(矩阵matrix和数组array),都可以用于处理行列表示的数字元素,虽然他们看起来很相似,但是在这两个数据类型上执行相同的运算可能得到不同的结果,其中Numpy函数库中的matrix与MATLAB中matrices等价。
二、Ndarray对象
Numpy中定义的最重要的对象是成为ndarray的N维数组类型。它描述相同类型的元素集合。可以使用基于零的索引访问集合中的项目。
大部分的数组操作仅仅是修改元数据部分,而不改变其底层的实际数据。数组的维数称为秩,简单来说就是如果你需要获取数组中一个特定元素所需的坐标数,如a是一个2×3×4的矩阵,你索引其中的一个元素必须给定三个坐标a[x,y,z],故它的维数就是3。
我们可以直接将数组看作一种新的数据类型,就像list、tuple、dict一样,但数组中所有元素的类型必须是一致的,Python支持的数据类型有整型、浮点型以及复数型,但这些类型不足以满足科学计算的需求,因此NumPy中添加了许多其他的数据类型,如bool、inti、int64、float32、complex64等。同时,它也有许多其特有的属性和方法。
常用ndarray属性:
- dtype 描述数组元素的类型
- shape 以tuple表示的数组形状
- ndim 数组的维度
- size 数组中元素的个数
- itemsize 数组中的元素在内存所占字节数
- T 数组的转置
- flat 返回一个数组的迭代器,对flat赋值将导致整个数组的元素被覆盖
- real/imag 给出复数数组的实部/虚部
- nbytes 数组占用的存储空间
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
ndarray 对象由计算机内存中的一维连续区域组成,带有将每个元素映射到内存块中某个位置的索引方案。 内存块以按行(C 风格)或按列(FORTRAN 或 MatLab 风格)的方式保存元素。
常用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() 返回满足条件的元素构成的数组
import numpy as np
a = np.arange(8)
print('原始数组:')
print(a)
输出:
原始数组:
[0 1 2 3 4 5 6 7]
#############################################
#reshape()返回一个给定shape的数组的副本
b = a.reshape(4,2)
print('修改后的数组:')
print(b)
输出:
修改后的数组:
[[0 1]
[2 3]
[4 5]
[6 7]]
##################################################
#resize(…)返回给定shape的数组,原数组shape发生改变
a.resize(2, 4)
print('修改后的数组:')
print(a)
输出:
修改后的数组:
[[0 1 2 3]
[4 5 6 7]]
##################################################
#flatten()/ravel() 返回展平数组,原数组不改变
print('展开的数组:')
print(a.flatten())
输出:
展开的数组:
[0 1 2 3 4 5 6 7]
数组的创建
ndarray
类的实例可以通过后面总结的关于数组的若干方法进行构造。 基本的ndarray
是使用NumPy中的数组函数创建的,如下所示:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
相关参数说明如下:
- object:任何暴露数组接口方法的对象都会返回一个数组或任何(嵌套)序列。
- dtype:数组的所需数据类型,可选。
- copy:默认为true,对象是否被复制,可选。
- order:C(按行)、F(按列)或A(任意,默认)。
- subok:默认情况下,返回的数组被强制为基类数组。 如果为true,则返回子类。
- ndmin:指定返回数组的最小维数。
1、一维数组的创建
可以使用numpy中的arange()函数创建一维有序数组,它是内置函数range的扩展版。
import numpy as np
ls1 = range(10)
print(list(ls1))
print(type(ls1))
ls2 = np.arange(10)
print(list(ls2))
print(type(ls2))
输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<class 'range'>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<class 'numpy.ndarray'>
如果一维数组不是一个规律的有序元素,而是人为的输入,就需要array()函数创建了。
import numpy as np
arr1 = np.array((1, 20, 13, 28, 22))
print (arr1)
print (type(arr1))
输出:
[ 1 20 13 28 22]
<type 'numpy.ndarray'>
2、二维数组的创建
二维数组的创建,其实在就是列表套列表或元组套元组。
import numpy as np
arr1 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
print (arr1)
print (type(arr1))
输出:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
<type 'numpy.ndarray'>
上面所介绍的都是人为设定的一维、二维或高维数组,numpy中也提供了几种特殊的数组,它们是:
ones函数 返回特定大小,以1填充的新数组
import numpy as np
a=np.ones(3)
b=np.ones((3,2))
print (a)
print ('-----------')
print (b)
输出:
[1. 1. 1.]
-----------
[[1. 1.]
[1. 1.]
[1. 1.]]
zeros函数 返回特定大小,以0填充的新数组
zeros(shape, dtype=float, order=’C’)
import numpy as np
a=np.zeros(5)
b=np.zeros((3,2))
print (a)
print ('-----------')
print (b)
输出:
[0. 0. 0. 0. 0.]
-----------
[[0. 0.]
[0. 0.]
[0. 0.]]
empty函数 它创建指定形状和dtype的未初始化数组
numpy.empty(shape, dtype = float, order = 'C')
注意:数组为随机值,因为他们未初始化。
import numpy as np
a=np.empty([3,2], dtype = int)
b=np.empty((3))
print (a)
print ('-----------')
print (b)
输出:
[[304742492 0]
[304809472 0]
[304808864 0]]
-----------
[1.49591833e-316 1.49743867e-316 1.50600276e-315]
ones_like zero_like empy_like函数 数组复制函数
注意:shape和dtype均复制
import numpy as np
a=np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]])
b=np.ones_like(a)
c=np.zeros_like(a)
d=np.empty_like(a)
print (a.shape)
print ('-----------')
print (b)
print ('-----------')
print (c)
print ('-----------')
print (d)
输出:
(3L, 2L, 2L)
-----------
[[[1 1]
[1 1]]
[[1 1]
[1 1]]
[[1 1]
[1 1]]]
-----------
[[[0 0]
[0 0]]
[[0 0]
[0 0]]
[[0 0]
[0 0]]]
-----------
[[[ 1633419382 1633972336]
[ 1817993588 1818321775]]
[[ 1835365468 1768971376]
[ 402432875 -2147453705]]
[[ 1865875575 828990325]
[ 1836412508 1851554160]]]
T 作用于矩阵,用于求矩阵的转置
import numpy as np
myMat=np.mat([[1,2,3],[4,5,6]])
print(myMat.T)
输出:
[[1 4]
[2 5]
[3 6]]
tolost()函数用于把一个矩阵转化为list列表
import numpy as np
myMat=np.mat([[1,2,3],[4,5,6]])
print myMat
print myMat.tolist()
输出:
[[1 2 3]
[4 5 6]]
[[1, 2, 3], [4, 5, 6]]
I 用于求矩阵的逆矩阵
import numpy as np
myMat=np.mat([[1,2,3],[4,5,6]])
print myMat
print myMat.I
输出:
[[1 2 3]
[4 5 6]]
[[-0.94444444 0.44444444]
[-0.11111111 0.11111111]
[ 0.72222222 -0.22222222]]
power(x1,x2) 数组的元素分别求n次方
x2可以是数字,也可以是数组,但是x1和x2的列数要相同
import numpy as np
x1 = range(6)
x2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0]
x3 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]])
print x1
print (np.power(x1, 3))
print (np.power(x1, x2))
print (np.power(x1, x3))
输出:
[0, 1, 2, 3, 4, 5]
[ 0 1 8 27 64 125]
[ 0. 1. 8. 27. 16. 5.]
[[ 0 1 8 27 16 5]
[ 0 1 8 27 16 5]]
reshape() 函数 依次生成n个自然数,并且以a行b列的数组形式显示
一般用法:numpy.arrange(n).reshape(a,b)
import numpy as np
a = np.arange(16).reshape(2,8) #生成16个自然数,以2行8列的形式显示
print a
输出:
[[ 0 1 2 3 4 5 6 7]
[ 8 9 10 11 12 13 14 15]]
特殊用法:mat(or array).reshape(c,-1)
必须是矩阵格式或者数组格式,才能使用.reshape(c,-1)函数,表示将此矩阵或者数组重组,以c行d 列的形式表示(-1的作用就在此,自动计算d:d=数组或者矩阵里面所有的元素个数(c,d必须为整数,不然会报错))
import numpy as np
a = np.arange(16).reshape(2,8) #生成16个自然数,以2行8列的形式显示
print a
print a.reshape(4,-1)
输出:
[[ 0 1 2 3 4 5 6 7]
[ 8 9 10 11 12 13 14 15]]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
np.unique() 去除数组中的重复数字,并进行排序之后输出
import numpy as np
a = [[1,2,3],[1,2,3],[2,3,4]]
resa = np.unique(a)
print resa
输出:
[1 2 3 4]
argsort() 返回的是数组值从小到达的索引值
import numpy as np
x = np.array([[0, 3], [2, 2]])
a = np.argsort(x, axis=0) #按列排序
b = np.argsort(x, axis=1) #按行排序
print a
print b
输出:
[[0 1]
[1 0]]
[[0 1]
[0 1]]
np.column_stack(tup)对竖轴的数组进行横向的操作
如果开始传入的是一维数组,首先将一维数组转化为二维数组
import numpy as np
a = np.array((1, 2, 3))
b = np.array((2, 3, 4))
c = np.column_stack((a, b))
print(a)
print(b)
print(c)
输出:
[1 2 3]
[2 3 4]
[[1 2]
[2 3]
[3 4]]
如果一开始传入的是多维数组,则直接进行拼接操作
import numpy as np
a = np.array(((1, 2, 3), (4, 3, 2)))
b = np.array(((2,3,4),(2,12,2)))
c = np.column_stack((a,b))
print(a)
print(b)
print(c)
输出:
[[1 2 3]
[4 3 2]]
[[ 2 3 4]
[ 2 12 2]]
[[ 1 2 3 2 3 4]
[ 4 3 2 2 12 2]]
三、Numpy数据类型
数据类型对象(dtype)
数据类型对象描述了对应于数组的固定内存块的解释,取决于以下方面:
- 数据类型(整数、浮点或者 Python 对象)
- 数据大小
- 字节序(小端或大端)
- 在结构化类型的情况下,字段的名称,每个字段的数据类型,和每个字段占用的内存块部分。
- 如果数据类型是子序列,它的形状和数据类型。
字节顺序取决于数据类型的前缀<或>。<意味着编码是小端(最小有效字节存储在最小地址中)。>意味着编码是大端(最大有效字节存储在最小地址中)。
dtype语法构造:
numpy.dtype(
object
, align, copy)
参数为:
Object:被转换为数据类型的对象。
Align:如果为
true
,则向字段添加间隔,使其类似 C 的结构体。
Copy: 生成dtype对象的新副本,如果为flase,结果是内建数据类型对象的引用。
# 首先创建结构化数据类型。
#int8,int16,int32,int64 可替换为等价的字符串 'i1','i2','i4',以及其他。
dt = np.dtype([('age', np.int8)])
print(dt)
# 现在将其应用于 ndarray 对象
dt = np.dtype([('age', np.int8)])
a = np.array([(10,), (20,), (30,)], dtype=dt)
print(a)
# 文件名称可用于访问 age 列的内容
dt = np.dtype([('age', np.int8)])
a = np.array([(10,), (20,), (30,)], dtype=dt)
print(a['age'])
输出:
[('age', 'i1')]
[(10,) (20,) (30,)]
[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:])
输出:
[0 1 2 3 4 5 6 7 8 9]
slice(2, 7, 2)
[2 4 6]
[2 4 6]
5
[2 3 4 5 6 7 8 9]
[2 3 4]
我们的数组是:
[[1 2 3]
[3 4 5]
[4 5 6]]
第二列的元素是:
[2 4 5]
第二行的元素是:
[3 4 5]
第二列及其剩余元素是:
[[2 3]
[4 5]
[5 6]]
五、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的文档:)
来源:oschina
链接:https://my.oschina.net/u/3696975/blog/3145108