python numpy常用操作_Numpy常用操作

numpy简介

Python中用列表(list)可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针。这样为了保存一个简单的[1,2,3],需要有3个指针和三个整数对象。对于数值运算来说这种结构显然比较浪费内存和CPU计算时间。

此外python还提供了一个array模块,array对象和列表不同,它直接保存数值,和C语言的一维数组比较类似。但是由于它不支持多维,也没有各种运算函数,因此也不适合做数值运算。

NumPy的诞生弥补了这些不足,NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。Numpy内部运算是通过C语言实现的,所以性能方面也很不错。

1、生成numpy的ndarray的几种方式

numpy提供了ndarray和matrix两种类型的数据,numpy的二维数组能够很好地实现矩阵的各种功能,而且比matrix要灵活,速度也更快。

numpy有ndarray和matix,性能方面ndarray优于matix,所以一般使用ndarray。

我们可以通过给array函数传递Python的序列对象创建数组,如果传递的是多层嵌套的序列,将创建多维数组。

(1)创建numpy的array几种方法

import numpy as np

a = np.array([1, 2, 3, 4])

b = np.array((5, 6, 7, 8))

##b的结果如下

array([5, 6, 7, 8])

c = np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]])

##c的结果如下

array([[ 1, 2, 3, 4],

[ 4, 5, 6, 7],

[ 7, 8, 9, 10]])

(2)利用numpy内置函数创建

zeros = np.zeros((2,2)) ###生成一个全为0的数组或矩阵

结果为:

array([[ 0., 0.],

[ 0., 0.]])

e = np.eye(2) ###生成一个单位矩阵

##结果如下:

array([[ 1., 0.],

[ 0., 1.]])

(3) 数组的大小可以通过其shape属性获得

c.ndim ##获取数组或矩阵维数

c.shape ##获取矩阵各维长度

c.shape[0] ##获取矩阵行数,shape[1]获取矩阵的列数

c.size ##获取矩阵的元素个数

c.dtype ##查看数组数据类型

(4)修改其形状

数组c的shape有两个元素,因此它是二维数组,其中第0轴的长度为3,第1轴的长度为4。还可以通过修改数组的shape属性,在保持数组元素个数不变的情况下,改变数组每个轴的长度。

c.reshape(4,3) ##把原来3x4矩阵,转换为4x3矩阵

##结果为:array([[ 1, 2, 3],

[ 4, 4, 5],

[ 6, 7, 7],

[ 8, 9, 10]])

c.reshape(2,-1) ###当某个轴的元素为-1时,将根据数组元素的个数自动计算 ###此轴的长度

(5)arange函数类似于python的range函数,通过指定开始值、终值和步长来创建一维数组,注意数组不包括终值:

np.arange(0,1,0.1)

##结果为:array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])

2、存取元素

(1)数组元素的存取方法和Python的标准方法相同

a = np.arange(10)

a

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

a[5] # 用整数作为下标可以获取数组中的某个元素

5

a[3:5] # 用范围作为下标获取数组的一个切片,包括a[3]不包括a[5]

##结果为:array([3, 4])

a[:-1] # 下标可以使用负数,表示从数组后往前数

结果为:array([0, 1, 2, 3, 4, 5, 6, 7, 8])

a[2:4] = 100,101 # 下标还可以用来修改元素的值

a

#结果为:array([ 0, 1, 40, 41, 4, 5, 6, 7, 8, 9])

a[1:-1:2] # 范围中的第三个参数表示步长,2表示隔一个元素取一个元素

#结果为:array([ 1, 41, 5, 7])

(2) 和Python的列表序列不同,通过下标范围获取的新的数组是原始数组的一个视图。它与原始数组共享同一块数据空间。

b = a[3:7] # 通过下标范围产生一个新的数组b,b和a共享同一块数据空间

b[2] = -10 # 将b的第2个元素修改为-10

#a结果如下

array([ 0, 1, 40, 41, 4, -10, 6, 7, 8, 9])

#b的结果如下

array([ 41, 4, -10, 6])

3、多维数组

创建一个6x6的多维数组或矩阵

a = np.arange(0, 60, 10).reshape(-1, 1) + np.arange(0, 6)

#运行结果如下:

array([[ 0, 1, 2, 3, 4, 5],

[10, 11, 12, 13, 14, 15],

[20, 21, 22, 23, 24, 25],

[30, 31, 32, 33, 34, 35],

[40, 41, 42, 43, 44, 45],

[50, 51, 52, 53, 54, 55]])

a[3:, [0, 2, 5]]

##下标中的第0轴是一个范围,它选取第3行之后的所有行; ##第1轴是整数序列,它选取第0, 2, 5三列

#运行结果为:

array([[30, 32, 35],

[40, 42, 45],

[50, 52, 55]])

a[2::2,::2]

##第0轴,从第2行开始,步长为2;第1轴,从第0行开始,步长为2

##运行结果为:

array([[20, 22, 24],

[40, 42, 44]])

4、矩阵操作

(1)以下介绍矩阵操作,包括两个矩阵间操作如矩阵乘法等。

A = np.array([[1, 2], [-1, 4]])

B = np.array([[2, 0], [3, 4]])

###对应元素相乘

A*B

##结果如下:

array([[ 2, 0],

[-3, 16]])

####矩阵乘法

np.dot(A, B) # 或者 A.dot(B)

##运行结果如下

array([[ 8, 8],

[10, 16]])

(2)线性代数运算

对矩阵进行线性代数运行,如求转置、特征向量等。求A的转置

##求A的转置

A.transpose() ##或A.T

##运行结果

array([[ 1, -1],

[ 2, 4]])

## 求A的逆矩阵

linalg.inv(A)

##运行结果

array([[ 0.66666667, -0.33333333],

[ 0.16666667, 0.16666667]])

# 求A的特征值和特征向量

eigenvalues, eigenvectors = linalg.eig(A)

##其中eigenvalues为 特征值,eigenvectors为特征向量

(3)调整坐标顺序

transpose的参数为坐标,正常顺序为(0, 1, 2, ... , n - 1),

现在传入的为(1, 0)代表C[x][y]转换为C[y][x],第0个和第1个坐标互换。

C.transpose((1,0)) ###第0个和第1个坐标互换

##结果如下:

array([[ 0.68752896, -0.11705268, 0.49078462, -0.48826679, -1.26943352,

-0.97029925],

[ 1.01686837, -1.55073073, -1.40240593, -0.98632156, 0.80378005,

0.33703986],

[ 0.95644284, -0.19360605, 1.82482162, -0.45383782, 0.26197213,

0.9131711 ]])

(4)在矩阵或数组上运用数学和统计方法

import numpy as np

import numpy.random as np_random

print('求和,求平均')

arr = np.random.randn(5, 4)

print(arr)

print(arr.mean())

print(arr.sum())

print(arr.mean(axis = 1)) # 对每一行的元素求平均

print(arr.sum(0)) # 对每一列元素求和,axis可以省略。

(5)向量或矩阵运算与循环运算性能比较

import time as tm

import numpy as np

dim = 100000#数据长度(包含的元素个数)

x1 = np.ones(dim)

x2 = np.ones(dim)

yFor = np.ones(dim)

tStart = tm.clock()#开始计时

#for循环解算x1*x2(对应元素相乘)

for i in range(dim):

yFor[i] = x1[i]*x2[i]

tEnd=tm.clock()#停止计时

tFor = tEnd-tStart#计算用时

tStart = tm.clock()#开始计时

#向量计算x1*x2(对应元素相乘)

yVector = x1*x2

tEnd = tm.clock()#停止计时

tVector = tEnd-tStart#计算用时

print ('for循环用时tFor=',tFor)

print ('向量运算用时tVector=',tVector)

5、 数据合拼与拆分

import numpy as np

import numpy.random as np_random

print('连接两个二维数组')

arr1 = np.array([[1, 2, 3], [4, 5, 6]])

arr2 = np.array([[7, 8, 9], [10, 11, 12]])

print(np.concatenate([arr1, arr2], axis = 0)) # 按行连接

print(np.concatenate([arr1, arr2], axis = 1)) # 按列连接

##或通过以下命令进行连接,效果一样

print('垂直stack与水平stack')

print(np.vstack((arr1, arr2))) # 垂直堆叠

print(np.hstack((arr1, arr2))) # 水平堆叠

6、numpy上的通用函数(ufunc)

ufunc是universal function的缩写,它是一种能对数组的每个元素进行操作的函数。NumPy内置的许多ufunc函数都是在c语言级别实现的,因此它们的计算速度非常快。让我们来看一个例子:

import time

import math

import numpy as np

x = [i * 0.001 for i in np.arange(1000000)]

start = time.clock()

for i, t in enumerate(x):

x[i] = math.sin(t)

print ("math.sin:", time.clock() - start )

x = [i * 0.001 for i in np.arange(1000000)]

x = np.array(x)

start = time.clock()

np.sin(x)

print ("numpy.sin:", time.clock() - start )

运行结果如下:

math.sin: 0.5793389999999974

numpy.sin: 0.06916299999999964

说明,numpy.sin比math.sin快10倍多。这得利于numpy.sin在C语言级别的循环计算。


版权声明:本文为weixin_35474542原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。