numpy 基础01

KinglyJn      2017-11-21

numpy简介

NumPy的全名为Numeric Python,是一个开源的Python科学计算库,它包括:

  • 一个强大的N维数组对象ndrray;
  • 比较成熟的(广播)函数库;
  • 用于整合C/C++和Fortran代码的工具包;
  • 实用的线性代数、傅里叶变换和随机数生成函数

NumPy的优点:

  • 对于同样的数值计算任务,使用NumPy要比直接编写Python代码便捷得多;
  • NumPy中的数组的存储效率和输入输出性能均远远优于Python中等价的基本数据结构,且其能够提升的性能是与数组中的元素成比例的;
  • NumPy的大部分代码都是用C语言写的,其底层算法在设计时就有着优异的性能,这使得NumPy比纯Python代码高效得多

当然,NumPy也有其不足之处,由于NumPy使用内存映射文件以达到最优的数据读写性能,而内存的大小限制了其对TB级大文件的处理;此外,NumPy数组的通用性不及Python提供的list容器。因此,在科学计算之外的领域,NumPy的优势也就不那么明显。


numpy的数组ndarray

NumPy最重要的一个特点就是其N维数组对象(即ndarray),该对象是一个快速而灵活的大数据集容器,该对象由两部分组成:

  • 实际的数据;
  • 描述这些数据的元数据;

大部分的数组操作仅仅是修改元数据部分,而不改变其底层的实际数据。数组的维数称为秩,简单来说就是如果你需要获取数组中一个特定元素所需的坐标数,如a是一个2×3×4的矩阵,你索引其中的一个元素必须给定三个坐标a[x,y,z],故它的维数就是3。而轴可以理解为一种对数组空间的分割,以数组a为例,如果我们以0为轴,那么a可以看成是一个由两个元素构成的数组,其中每个元素都是一个3×4的数组。 我们可以直接将数组看作一种新的数据类型,就像list、tuple、dict一样,但数组中所有元素的类型必须是一致的,Python支持的数据类型有整型、浮点型以及复数型,但这些类型不足以满足科学计算的需求,因此NumPy中添加了许多其他的数据类型,如bool、inti、int64、float32、complex64等。同时,它也有许多其特有的属性和方法。

常用ndarray属性:

  • dtype 描述数组元素的类型
  • shape 以tuple表示的数组形状
  • ndim 数组的维度
  • size 数组中元素的个数
  • itemsize 数组中的元素在内存所占字节数
  • T 数组的转置
  • flat 返回一个数组的迭代器,对flat赋值将导致整个数组的元素被覆盖
  • real/imag 给出复数数组的实部/虚部
  • nbytes 数组占用的存储空间

常用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代码测试

numpy.array的常见性质

import numpy as np
matrix = np.array([[1,2,3], [4,5,6]])
print (matrix)
print ("矩阵元素的类型: ", matrix.dtype)
print ("矩阵的型: ", matrix.shape)
print ("矩阵元素的总个数: ", matrix.size)
print ("矩阵每个元素所占字节数: ", matrix.itemsize)
print ("矩阵所占存储空间(size*itemsize)", matrix.nbytes)

'''
[[1 2 3]
 [4 5 6]]
矩阵元素的类型:  int64
矩阵的型:  (2, 3)
矩阵元素的总个数:  6
矩阵每个元素所占字节数:  8
矩阵所占存储空间(size*itemsize) 48
'''


numpy读文件操作(后实际工程中使用pandas读取文件)

'''
aaa.txt文件内容
--------------
Year,t1,t2,t3,t4
1986,t11,t21,t31,23
1987,t12,t22,t32,121
1988,t13,t23,t33,123
1989,t14,t24,t34,125
--------------
'''

import numpy as np
t = np.genfromtxt('aaa.txt', delimiter=',', dtype=str, skip_header=1)
print (t)
print ("返回(1,1)索引处的元素值: ", t[1,1])
print ("返回第[1,),第[1,3)列的元素:\n", t[1:, 1:3])

'''
[['1986' 't11' 't21' 't31' '23']
 ['1987' 't12' 't22' 't32' '121']
 ['1988' 't13' 't23' 't33' '123']
 ['1989' 't14' 't24' 't34' '125']]
返回(1,1)索引处的元素值:  t12
返回第[1,),第[1,3)列的元素:
 [['t12' 't22']
 ['t13' 't23']
 ['t14' 't24']]
'''


生成一个矩阵测试

import numpy as np
a = np.arange(1,13,1)
b = np.reshape(a, (3,4))
c = b.T
print ("变换矩阵形状以返回新的矩阵(原来的矩阵a不变):\n", b)
print ("拉长矩阵成一个向量:\n", np.ravel(b))
print ("转置一个矩阵:\n", c)
print ("生成一个[0-n)的坐标向量,步长为1:\n", np.arange(15))
print ("生成一个[n1,n2)的坐标向量,步长为step:\n", np.arange(10,30,5))
print ("生成一个[n1,n2)的坐标向量,在n1-n2中取m个点:\n", np.linspace(0,5,11))
print ("以某个坐标向量计算对应函数的函数值:\n", np.sin( np.linspace(0,5,11) ))
print ("初始化一个零矩阵:\n", np.zeros((3,4), dtype=np.int32) )
print ("初始化一个单位矩阵:\n", np.ones((3,4), dtype=np.int32) )
print ("初始化一个对角矩阵:\n", np.eye(3, dtype=np.int32) )
print ("初始化一个[0,1]的随机数矩阵:\n", np.random.random((3,4)) )
print ("将矩阵元素类型转化为float类型(注意原来的矩阵不变):\n", a.astype(float))


'''
变换矩阵形状以返回新的矩阵(原来的矩阵a不变):
 [[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
拉长矩阵成一个向量:
 [ 1  2  3  4  5  6  7  8  9 10 11 12]
转置一个矩阵:
 [[ 1  5  9]
 [ 2  6 10]
 [ 3  7 11]
 [ 4  8 12]]
生成一个[0-n)的坐标向量,步长为1:
 [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]
生成一个[n1,n2)的坐标向量,步长为step:
 [10 15 20 25]
生成一个[n1,n2)的坐标向量,在n1-n2中取m个点:
 [ 0.   0.5  1.   1.5  2.   2.5  3.   3.5  4.   4.5  5. ]
以某个坐标向量计算对应函数的函数值:
 [ 0.          0.47942554  0.84147098  0.99749499  0.90929743  0.59847214
  0.14112001 -0.35078323 -0.7568025  -0.97753012 -0.95892427]
初始化一个零矩阵:
 [[0 0 0 0]
 [0 0 0 0]
 [0 0 0 0]]
初始化一个单位矩阵:
 [[1 1 1 1]
 [1 1 1 1]
 [1 1 1 1]]
初始化一个对角矩阵:
 [[1 0 0]
 [0 1 0]
 [0 0 1]]
初始化一个[0,1]的随机数矩阵:
 [[ 0.43773892  0.83449877  0.18528594  0.20617703]
 [ 0.35807278  0.98608549  0.62804758  0.52031105]
 [ 0.12416385  0.58041098  0.37101375  0.92966848]]
将矩阵元素类型转化为float类型(注意原来的矩阵不变):
 [  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.]
'''


numpy算数运算测试

import numpy as np
v = np.array([[1,2,3], [4,5,6], [7,8,9]])
print (v)
print ("判断每个元素等于某个值,运算结果是一个同型矩阵:\n", v==5)
print ("以矩阵的对应元素为指数,以e为底的数组成的新的矩阵:\n", np.exp(v))
print ("矩阵的每个元素开平方后对应的矩阵:\n", np.sqrt(a))
print ("矩阵的每个元素向下取整后得到的矩阵:\n", np.floor(a))
print ("矩阵每个元素乘以某个值:\n", v*2)
print ("两个矩阵相加减:\n", v+v)
print ("两个矩阵做内积(对应位置元素值相乘):\n", v*v)
print ("两个矩阵相乘(行乘列的和A.dot(B) 或 np.dot(A,B) ):\n", v.dot(v))
print ("取出元素值为5或6的元素组成新的向量:\n", v[(v==5)|(v==6)])
print ("矩阵的最小值:\n", v.min())
print ("矩阵的最大值:\n", v.max())
print ("矩阵的行最大值索引\n", v.argmax(axis=1) )
print ("矩阵的列最大值索引\n", v.argmax(axis=0) )
print ("矩阵的行元素求和,返回新的向量:\n", v.sum(axis=1))

'''
[[1 2 3]
 [4 5 6]
 [7 8 9]]
判断每个元素等于某个值,运算结果是一个同型矩阵:
 [[False False False]
 [False  True False]
 [False False False]]
以矩阵的对应元素为指数,以e为底的数组成的新的矩阵:
 [[  2.71828183e+00   7.38905610e+00   2.00855369e+01]
 [  5.45981500e+01   1.48413159e+02   4.03428793e+02]
 [  1.09663316e+03   2.98095799e+03   8.10308393e+03]]
矩阵的每个元素开平方后对应的矩阵:
 [ 1.          1.41421356  1.73205081  2.          2.23606798  2.44948974
  2.64575131  2.82842712  3.          3.16227766  3.31662479  3.46410162]
矩阵的每个元素向下取整后得到的矩阵:
 [  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.]
矩阵每个元素乘以某个值:
 [[ 2  4  6]
 [ 8 10 12]
 [14 16 18]]
两个矩阵相加减:
 [[ 2  4  6]
 [ 8 10 12]
 [14 16 18]]
两个矩阵做内积(对应位置元素值相乘):
 [[ 1  4  9]
 [16 25 36]
 [49 64 81]]
两个矩阵相乘(行乘列的和A.dot(B) 或 np.dot(A,B) ):
 [[ 30  36  42]
 [ 66  81  96]
 [102 126 150]]
取出元素值为5或6的元素组成新的向量:
 [5 6]
矩阵的最小值:
 1
矩阵的最大值:
 9
矩阵的行最大值索引
 [2 2 2]
矩阵的列最大值索引
 [2 2 2]
矩阵的行元素求和,返回新的向量:
 [ 6 15 24]
'''


复制矩阵

import numpy as np
#深度复制矩阵(改变其中一个,不会对另一个有影响)
a = np.arange(1,10,1)
c = a.copy()
c[0] = 100
print ("深度复制矩阵测试: a,c=\n", a, c)
print (id(c))
print (id(a))

#浅度复制矩阵(改变其中一个,会对另外一个的矩阵值有影响,因为两个对象的矩阵指向的是同一个)
a = np.arange(1,10,1)
c = a.view()
c[0] = 100
print ("浅度复制矩阵测试: a,c=\n", a, c)
print (id(c))
print (id(a))

#砖块复制矩阵
a = np.array([[1,2], [3,4]])
print ("砖块复制矩阵测试:\n", np.tile(a, (2,3)) )


'''
深度复制矩阵测试: a,c=
 [1 2 3 4 5 6 7 8 9] [100   2   3   4   5   6   7   8   9]
4516995840
4516996960
浅度复制矩阵测试: a,c=
 [100   2   3   4   5   6   7   8   9] [100   2   3   4   5   6   7   8   9]
4516996960
4516997520
砖块复制矩阵测试:
 [[1 2 1 2 1 2]
 [3 4 3 4 3 4]
 [1 2 1 2 1 2]
 [3 4 3 4 3 4]]
'''


拼接矩阵

import numpy as np
a = [[1,2,3], [4,5,6]]
b = [[7,8,9], [10,11,12]]
print ("在列的方向上拼接矩阵:\n", np.vstack((a,b)) )
print ("在行的方向上拼接矩阵:\n", np.hstack((a,b)) )


'''
在列的方向上拼接矩阵:
 [[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
在行的方向上拼接矩阵:
 [[ 1  2  3  7  8  9]
 [ 4  5  6 10 11 12]]
'''


切分矩阵

import numpy as np
#切分矩阵
c = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16]])
print ("原矩阵:\n", c)
print ("在行的方向上平均切分矩阵成2份:\n", np.vsplit(c, 2))
print ("在列的方向上平均切分矩阵成2份:\n", np.hsplit(c, 2))


'''
原矩阵:
 [[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]
 [13 14 15 16]]
在行的方向上平均切分矩阵成2份:
 [array([[1, 2, 3, 4],
       [5, 6, 7, 8]]), array([[ 9, 10, 11, 12],
       [13, 14, 15, 16]])]
在列的方向上平均切分矩阵成2份:
 [array([[ 1,  2],
       [ 5,  6],
       [ 9, 10],
       [13, 14]]), array([[ 3,  4],
       [ 7,  8],
       [11, 12],
       [15, 16]])]
'''


矩阵元素排序

import numpy as np
a = np.array([[11,9,5,5], [4,3,2,5], [6,2,3,5]])
print ("原矩阵:\n", a)
print ("按行排序:\n", np.sort(a, axis=1))
print ("按列排序:\n", np.sort(a, axis=0))

'''
原矩阵:
 [[11  9  5  5]
 [ 4  3  2  5]
 [ 6  2  3  5]]
按行排序:
 [[ 5  5  9 11]
 [ 2  3  4  5]
 [ 2  3  5  6]]
按列排序:
 [[ 4  2  2  5]
 [ 6  3  3  5]
 [11  9  5  5]]
'''

Tags:


Share: