Python NumPy学习总结

老子叫甜甜 提交于 2019-12-19 21:02:35

【推荐】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的文档:)

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!