import numpy as np
生成矩阵
numpy中的数据类型为ndarray,生成ndarray有两种方法:使用numpy函数生成或将其他类型转换成ndarray。
生成矩阵:
np.arange(5)
array([0, 1, 2, 3, 4])
np.random.rand(2,3) #[0,1)区间随机矩阵
array([[0.43177325, 0.47276096, 0.39337971],
[0.21972166, 0.34112265, 0.71146348]])
np.random.randn(2,4) #正态分布随机矩阵
array([[ 1.02128782, -0.24218818, 0.12195008, 0.93265206],
[-1.15082712, 0.73436284, -1.85574288, 1.17365222]])
下列生成函数接受元组形式的维度参数。
np.zeros((1,2))
array([[0., 0.]])
np.ones((2,3,4))
将其他类型转换成矩阵:
arr=[[1,2,3],[4.5,4.6,4.7]]
np.array(arr)
ndarray属性
ndarray常用的属性有:维度dim,形状shape,数据类型dtype。
arr=np.zeros((2,3))
arr.ndim
2
arr.shape
(2, 3)
arr.reshape((-1,6))
array([[0., 0., 0., 0., 0., 0.]])
arr.dtype
dtype(‘float64’)
转换类型:
arr_int=arr.astype(int)
arr_int.dtype
dtype(‘int32’)
基本运算
四则运算
matrix_1=np.ones((2,3))
matrix_2=np.ones((1,3))
matrix_3=np.ones((2,1))
matrix_1+1
matrix_1-matrix_2
matrix_1+matrix_3
会出现上述结果是因为numpy自带广播机制,程序会自动判断进行运算的第二个操作数是否可横向、纵向或同时纵横扩展成与第一个操作数相同形状,如果可以扩展,则进行扩展再运算;若不能扩展则报错。下述例子就属于无法广播的情况:
matrix_1=np.ones((2,3))
matrix_2=np.ones((3,2))
matrix_1+matrix_2
出错。
布尔运算
同形状的两矩阵做比较运算会直接输出布尔矩阵:
matrix_1=np.random.randn(2,2)
matrix_2=np.random.randn(2,2)
matrix_2>matrix_1
高阶运算
matrix=np.arange(6).reshape((2,3))
np.sqrt(matrix)
np.exp(matrix)
X=np.random.randn(2,3)
Y=np.random.randn(2,3)
np.maximum(X,Y) #一一比较取大值
matrix=np.random.randn(2,3)
remainder,whole_part=np.modf(matrix) #分别返回数值的小数与整数部分
print("{}\n{}\n{}".format(matrix,whole_part,remainder))
基本索引与切片
matrix=np.random.randn(3,3)
print(matrix)
连续索引:
#第二行
matrix[1,:]
array([ 1.95083543, -0.135785 , -1.2200805 ])
#第二列
matrix[:,1]
array([ 1.12415713, -0.135785 , -0.24464055])
#第二行第二列
matrix[1,1]
-0.13578499849769984
#前两行、后两列
matrix[:2,1:]
非连续索引:
#第一、三行的第二列
matrix[[0,2],1]
array([ 1.12415713, -0.24464055])
#对角线元素
matrix[[0,1,2],[0,1,2]]
array([-0.84123981, -0.135785 , 0.33912715])
#四个角落元素,此处比较难理解
matrix[[0,-1]][:,[0,-1]]
注意:非连续索引方式与连续索引方式有一个重要的区别,连续索引是以指针形式引用原数据,而非连续索引会将索引出的数据复制到一个新矩阵中。比较以下三种方法:
#连续索引,指针引用
matrix=np.ones((2,2))
arr=matrix[0,:] #arr可看作是一个指针引用
arr[:]=0
print(matrix)
#copy操作
matrix=np.ones((2,2))
arr=matrix[0,:].copy()
arr[:]=0
print(matrix)
#非连续索引,自带copy操作
matrix=np.ones((2,2))
arr=matrix[[1],[1]] #此步有copy操作
arr[:]=0
print(matrix)
布尔索引
假设这有4个人的数据,不过原数据没有行列的附加信息,需要根据名字顺序查找出对应的数据,可以使用布尔索引。
names=np.array(['name_1','name_2','name_3','name_4'])
info=np.array(['attr_1','attr_2','attr_3','attr_4'])
data=np.random.randn(4,4)
data
data[names=='name_2',info=='attr_3']
array([0.53087052])
所有能产生布尔结果的运算符都适用:
data[(names!='name_1')&(names!='name_3'),:]
data[data<0]=0
data
矩阵运算
matrix=np.arange(6).reshape((2,3))
matrix.T #矩阵转置
np.dot(matrix,matrix.T) #矩阵乘法
网格
X_range=np.arange(-3,3,0.5)
Y_range=np.arange(-3,3,0.5)
X,Y=np.meshgrid(X_range,Y_range) #以给定的范围生成网格坐标点
import matplotlib.pyplot as plt
plt.plot(X, Y, marker='.', color='blue', linestyle='none')
plt.show()
Z=np.sqrt(X**2+Y**2)
plt.imshow(Z,cmap=plt.cm.gray)
plt.colorbar()
plt.title("Image plot of $\sqrt{X^2+Y^2}$ for a grid of values")
plt.show()
统计方法
matrix=np.arange(8).reshape((2,4))
print("mean:{},sum:{},std:{}".format(matrix.mean(),matrix.sum(),matrix.std()))
print("max:{},argmax:{},min:{},argmin:{}".format(matrix.max(),matrix.argmax(),matrix.min(),matrix.argmin()))
print("行均值:{},列求和:{}".format(matrix.mean(axis=1),matrix.sum(axis=0)))
arr=np.arange(5)
arr.cumsum() #逐元素累加
array([ 0, 1, 3, 6, 10], dtype=int32)
matrix=np.arange(9).reshape((3,3))
matrix.cumsum(axis=1) #每行逐元素累加
arr=np.arange(1,5)
weights=np.arange(4,0,-1)
np.average(arr,weights=weights) #加权平均
2.0
条件操作
matrix=np.random.randn(3,3)
np.where(matrix>0,1,-1) #相当于python三元运算x=1 if x>0 else -1
matrix=np.random.randn(3,3)
(matrix>0).sum() #计算有几个大于零的值
5
排序
arr=np.random.randn(5)
arr.sort()
arr
array([-0.37303632, -0.303254 , 0.21750536, 0.48186136, 0.94146911])
matrix=np.random.randn(3,3)
matrix.sort(axis=1) #水平方向排序
matrix
一种有效计算分位数的方法就是将数组排序后直接取出相应位置的数:
arr=np.random.randn(1000)
arr.sort()
arr[int(len(arr)*0.25)] #随机数组的四分位数
-0.7105883272693553
独特值
names=np.array(['Bob','Joe','Will','Joe','Will'])
np.unique(names)
array([‘Bob’, ‘Joe’, ‘Will’], dtype=’
values=np.array([1,2,3,4,5,6,7,8,9])
np.in1d(values,[1,3,5,7,9]) #判断前者元素是否存在与后者中
array([ True, False, True, False, True, False, True, False, True])