目录
六、nadarry数组的运算
数组不用编写循环,即可对数据执行批量操作。这通常就叫做矢量化(vectorization)。数组之间的任何算术运算,都会将运算运用到元素级。
1.轴和秩
轴(axes):数组中的每一个维度被称为一个轴。
秩(rank):轴的个数
np.sum() # 计算所有元素的和
2. 数组与标量之间的运算
数组与标量之间的运算作用于数组的每一个元素
a = np.arange(12).reshape((2, 6))
print(a)
print(a + 2)
"""
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
"""
"""
[[ 2 3 4 5 6 7]
[ 8 9 10 11 12 13]]
"""
b = a.mean() # 求平均值
3. 相等形状数组间,加减乘除四则运算
arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([2, 2, 5, 5])
print(arr1+arr2)
print(arr1-arr2)
print(arr1*arr2)
print(arr1/arr2)
# 打印
[3, 4, 8, 9]
[-1, 0, -2, -1]
[ 2,4, 15, 20]
[0.5, 1., 0.6, 0.8]
4. 大小不等的数组间的运算
数组大小不等之间的运算叫做:广播(broadcasting),可以参考链接详细了解。
arr1 = np.array([1, 2, 3, 4])
arr3 = np.array([4])
print(arr1+arr3)
print(arr1-arr3)
print(arr1*arr3)
print(arr1/arr3)
"""
[5, 6, 7, 8]
[-3, -2, -1, 0]
[ 4, 8, 12, 16]
[0.25, 0.5, 0.75, 1. ]
"""
5. 删除
np.delete(arr, obj, axis=None)
参数 | 说明 |
---|---|
arr | 数组 |
obj | 待删除的元素的索引 |
axis | 方向,如果为空,则将obj应用于扁平数组 |
例子:
arr = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
# 打印
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
# 删除操作
np.delete(arr, [1,3,5], None)
# 结果
array([ 1, 3, 5, 7, 8, 9, 10, 11, 12])
6. 插入
用法1:指定位置插入
np.insert(arr, obj, values, axis=None)
参数 | 说明 |
---|---|
arr | 数组 |
obj | 待插入的元素的索引位置 |
values | 待插入的值 |
axis | 方向,如果为空,则将obj应用于扁平数组 |
例子:
a = np.array([[1, 1], [2, 2], [3, 3]])
# print
array([[1, 1],
[2, 2],
[3, 3]])
# 插入
np.insert(a, 1, 5, axis=1)
# 结果
array([[1, 5, 1],
[2, 5, 2],
[3, 5, 3]])
用法2:向后插入
np.append(arr, values, axis=None)
参数 | 说明 |
---|---|
arr | 数组 |
values | 待插入的值 |
axis | 方向,如果为空,则将obj应用于扁平数组 |
np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]])
# 结果
# array([1, 2, 3, 4, 5, 6, 7, 8, 9])
当轴指定时,values值的形状shape属性必须匹配前面的数组arr
### 1.
# 形状匹配时
np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0)
# 结果正确
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
### 2.
# 形状不匹配时
np.append([[1, 2, 3], [4, 5, 6]], [7, 8, 9], axis=0)
# 结果,报错
Traceback (most recent call last):...
七、通用函数
1. 一元函数
对ndarray中的数据执行元素级运算的函数
函数 | 说明 |
---|---|
np.sum(x) | 计算数组所有元素的和 |
np.prod(x) | 计算数组所有元素的乘积 |
np.diff(x) | 计算数组相邻元素之间的差 |
np.abs(x) np.fabs(x) | 计算数组各元素的绝对值 |
np.sqrt(x) | 计算数组各元素的平方根 |
np.square(x) | 计算数组各元素的平方 |
np.log(x), np.log10(x) np.log2(x) | 计算数组各元素的自然对数、10底对数和2底对数 |
np.ceil(x) np.floor(x) | 计算数组各元素的ceiling值或floor值 |
np.rint(x) | 计算数组各元素的四舍五入值 |
np.modf(x) | 计算数组各元素的小数和整数部分以两个独立数组形式返回 |
np.cos(x) np.cosh(x) np.sin(x) np.sinh(x) np.tan(x) np.tanh(x) | 计算数组各元素的普通型和双曲型三角函数 |
arccos, arccosh, arcsin, arcsinh, arctan, arctanh | 反三角函数和双曲型反三角函数 |
np.exp(x) | 计算各元素的指数值 |
np.sign(x) | 计算数组各元素的符号值:1(+),0,-1(-) |
np.rint(x) | 将各元素值四舍五入到最接近的整数,保留dtype |
np.isinf(x) | 判断是否是无穷 |
np.logical_not() | 计算元素not x的真值,同~ |
例子:
print '一元ufunc示例'
x = numpy.arange(6)
print(x) # [0 1 2 3 4 5]
print(numpy.square(x)) # [ 0 1 4 9 16 25]
x = numpy.array([1.5,1.6,1.7,1.8])
y,z = numpy.modf(x)
print(y)# [ 0.5 0.6 0.7 0.8]
print(z) # [ 1. 1. 1. 1.]
2. 二元函数
函数 | 说明 |
---|---|
+ - * / ** | 两个数组各元素进行对应运算 |
np.maximum(x, y) np.fmax() np.minimum(x, y) np.fim() | 元素级的最大值/最小值计算 |
np.mod(x, y) | 取余 |
np.copysign(x, y) | 将数组y中各元素值的符号赋值给数组x对应元素 |
> < >= <= == != | 算数比较,产生布尔型数组 |
np.add() | 相加 |
np.subtract() | 相减 |
np.mutiply() | 相乘 (一一对应乘) |
np.dot() | 矩阵内积 (按公式乘) |
np.vdot() | 两个向量的点积 |
np…inner() | 一维数组的向量内积 |
np.divide() | 相除 |
np.floor_divide() | 向下圆整除法(丢弃余数) |
np.power(arr,B) | 次方,arr内每个元素的B次方 |
np.greater(), np.greater_equal(), np.less(), np.less_equal(), np.equal(), np.not_equal() | >, >=, <, <=, =, != |
np.logical_and() | & 的函数表达式 |
np.logical_or() | | 的函数表达式 |
np.logical_xor() | ^ 的函数表达式 |
np.ix_() | 生成一个索引器,用于Fancy indexing(花式索引) |
np.linalg.det() | 计算输入矩阵的行列式 |
np.inalg.solve() | 计算矩阵形式的线性方程的解 |
# np.linalg.det()
a=np.array([[1,2],[3,4]])
print(np.linalg.det(a))
# -2.0000000000000004
b=np.array([[6,1,1],[4,-2,5],[2,8,7]])
print(b)
"""
[[ 6 1 1]
[ 4 -2 5]
[ 2 8 7]]
"""
print(np.linalg.det(b))
# -306.0
print(6*(-2*7-5*8)-1*(4*7-5*2)+(4*8- -2*2))
# -306
# -------------------------------------
# np.inalg.solve()
x=np.array([[1,2],[3,4]])
y=np.linalg.inv(x)
print(x)
"""
array([[1, 2],
[3, 4]])
"""
print(y)
"""
array([[-2. , 1. ],
[ 1.5, -0.5]])
"""
np.dot(x,y)
"""
array([[1.0000000e+00, 0.0000000e+00],
[8.8817842e-16, 1.0000000e+00]])
"""
a=np.array([[1,1,1],[0,2,5],[2,5,-1]])
print('数组a:')
print(a)
"""
数组a:
[[ 1 1 1]
[ 0 2 5]
[ 2 5 -1]]
"""
ainv=np.linalg.inv(a)
print('a的逆矩阵')
print(ainv)
"""
a的逆矩阵
[[ 1.28571429 -0.28571429 -0.14285714]
[-0.47619048 0.14285714 0.23809524]
[ 0.19047619 0.14285714 -0.0952381 ]]
"""
print('矩阵b:')
b=np.array([[6],[-4],[27]])
print(b)
"""
矩阵b:
[[ 6]
[-4]
[27]]
"""
print('计算:A^(-1)B:')
x=np.linalg.solve(a,b)
print(x)
"""
计算:A^(-1)B:
[[ 5.]
[ 3.]
[-2.]]
"""
3. 聚合函数 - 数学与统计方法
通过数组上一组数学函数,对整个数组或者某个轴向数据进行统计计算。
下列聚合函数的聚合计算(aggregation,通常叫做约简(reduction))。
既可以当做数组的实例方法调用(如:arr1.sum()),也可以当做顶级Numpy函数使用(如:np.sum(arr1))。并且在使用的时候可以指定具体哪个轴(axis),计算轴方向上的统计结果。
函数 | NAN安全版本 | 描述 |
---|---|---|
np.sum(arr1) | np.nansum() | 计算元素的和 |
np.prod(arr1) | np.nanprod() | 计算元素的积 |
np.mean(arr1) | np.nanmean() | 计算元素平均值 |
np.std(arr1) | np.nanstd() | 计算元素的标准差 |
np.var(arr1) | np.nanvar() | 计算元素的方差 |
np.min(arr1) | np.nanmin() | 获得元素的最小值 |
np.max(arr1) | np.nanmax() | 获得数组中元素的最大值 |
np.argmin(arr1) | np.nanargmin() | 获得数组中最小值的索引 |
np.argmax(arr1) | np.nanargmax() | 获得最大值的索引 |
np.median(arr1) | np.nanmedian() | 获得元素的中位数 |
np.minimum(arr1, arr2) | np.fmin() | 获得多个数组中元素最小值 |
np.maximun(arr1, arr2) | np.fmax() | 获得多个数组中元素最大值 |
np.cumsum() | 元素的逐渐累计和数组 | |
np.cumprod() | 元素的逐渐累计积数组 |
numpy的sum函数比python内置sum函数效率要高,例如:
nums = np.random.rand(1000000)
%timeit sum(nums)
%timeit np.sum(nums)
sum(nums):
np.sum(nums):
4. 布尔函数- any()和all()
产生布尔数组的函数
np.all(self, axis=None, out=None, keepdims=False)
np.any(self, axis=None, out=None, keepdims=False)
注意: 有self就代表,不仅可以以Numpy函数调用,也可以以数组实例方法调用。
不指定轴axis,则默认为操作所有元素,即变成一维来进行操作。
函数 | 描述 |
---|---|
np.any() | 是否有一个元素为True |
np.all() | 是否所有元素为True |
例子:查看所有数组是否都为0。
np.all(array==0)
or
(array==0).all()
5. 矩阵函数
函数 | 说明 |
---|---|
np.diag(array) | 以一维数组的形式返回方阵的对角线(或非对角线)元素 |
np.diag([x,y,…]) | 将一维数组转化为方阵(非对角线元素为0) |
np.dot(ndarray, ndarray) | 矩阵相乘 |
np.trace(ndarray) | 计算矩阵对角线元素的和 |
np.mat / matrix | 创建矩阵 |
np.bmat(array) | 数组变矩阵 |
matrix.H | 求共轭转置,实部不变,虚部相反 |
matrix.I | 求逆矩阵(不能是奇异矩阵,即不可逆矩阵) |
matrix.T | 求矩阵的转置 |
6. 排序函数
跟Python内置列表类型一样,Numpy数组也可以通过sort方法排序。
函数 | 说明 |
---|---|
np.sort(ndarray) | 排序,返回副本,默认升序 |
np.sort(-ndarray) | 降序排序 |
np.argsort(ndarray) | 返回排序后的下标值 |
sort()函数用法:
np.sort(self, axis=-1, kind='quicksort', order=None)
axis - 沿着那个轴排序。默认为-1,意味着,默认以最内层或最大轴序号为标准排序。
kind - 排序算法,有'quicksort', 'mergesort', 'heapsort', 'stable'。默认为快速排序。
# order - 字符串或字符串列表。制定指定排序顺序列表。
例子:
arr1 = np.random.randint(1, 20, size=12)
print(arr1) # 排序前
# [19 12 15 7 15 9 9 14 7 19 11 14]
arr1.sort()
print(arr1) # 排序后
# [ 7 7 9 9 11 12 14 14 15 15 19 19]
print(arr1[int(0.05*len(arr1))]) # 5%分位数
# 7
7. 去重以及集合运算
函数 | 说明 |
---|---|
unique(x) | 计算x中的唯一元素,并返回有序结果 |
intersectd(x, y) | 计算x和y中的公共元素,并返回有序结果 |
union1d(x, y) | 计算x和y中的并集,并返回有序结果 |
in1d(x, y) | 得到一个表示“x的元素是否包含于y”的布尔型数组 |
setdiff1d(x, y) | 集合的差,即元素在x中且不在y中 |
setxor1d(x, y) | 集合的对称差,即存在于一个数组中但不同时存在与两个数组中的元素 |
x = np.array([[1, 6, 2], [6, 1, 3], [1, 5, 2]])
print(np.unique(x)) # [1,2,3,5,6]
y = np.array([1, 6, 5])
print(np.in1d(x, y)) # [ True True False True True False True True False]
print(np.setdiff1d(x, y)) # [2 3]
print(np.intersect1d(x, y)) # [1 5 6]
1. 去掉缺失值
在函数前使用波浪号~,表示"反义"
arr = np.array([1,2,3,np.nan,4,5,6,np.nan,9])
arr
# 打印arr
array([ 1., 2., 3., nan, 4., 5., 6., nan, 9.])
arr[~np.isnan(arr)]
# 结果
array([1., 2., 3., 4., 5., 6., 9.])
2. 去除重复值
对重复的值,删减保留唯一一项
有对应函数,可以直接删除多余项
np.random.seed(3)
n1 = np.random.randint(0,15,size=6)
n1
# 打印
array([10, 8, 9, 3, 8, 8])
rs = np.unique(n1)
rs
# 打印
array([ 3, 8, 9, 10])
3. 去除所有重复值
对重复的值,全部删除
无对应函数,需要手动实现
np.random.seed(45)
n1 = np.random.randint(0,15,size=(4,4))
n1
# 打印 n1
array([[11, 14, 3, 12],
[ 0, 13, 5, 3],
[ 4, 9, 8, 1],
[14, 5, 9, 6]])
# un表示所有值的数量
un = np.unique(n1, return_counts=True)
# 去除所有重复值,方法1
un[0][un[1]==1]
# 去除所有重复值,方法2
np.array(set(n1.flatten().tolist()))
8. 其他补充函数
函数 | 说明 |
---|---|
np.linspace(x, y, n) | 将制定的[x, y]平均分成n份,即等差数列 |
np.take(a, indexs) | 从a中根据下标index提取元素 |
np.apply_along_axis(func1d, axis,arr) | 沿着某个轴执行指定函数(文档有详细例子) |
np.unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None) | 去除数组中的重复元素 |
八、where条件逻辑函数
前面使用过条件逻辑表达式,但是还有一种,在处理复杂度高的条件时,更为简便的方法。
import numpy as np
n1 = np.random.randint(2, 10, size=(4, 4))
n1
# 结果
array([[7, 4, 3, 6],
[8, 3, 3, 5],
[2, 5, 4, 7],
[6, 8, 4, 8]])
1. 使用条件表达式替换值(改变原数组)
n1[n1>5] = 0
n1
# 结果
array([[0, 4, 3, 0],
[0, 3, 3, 5],
[2, 5, 4, 0],
[0, 0, 4, 0]])
2. 使用where函数来替换值(不改变原数组)
np.where(condition, x, y)
参数 | 说明 |
---|---|
condition | 判断条件,或者布尔掩码(布尔索引) |
x | 替换成为的值 |
y | 待替换的数组 |
若无x和y,则直接返回条件判断结果的索引
np.where([[True, False], [True, True]],
[[1, 2], [3, 4]],
[[9, 8], [7, 6]])
# 结果
array([[1, 8],
[3, 4]])
九、ndarray数组的元素重复操作
x = numpy.array([[1,2],[3,4]])
print(x.repeat(2)) # 按元素重复 [1 1 2 2 3 3 4 4]
print(x.repeat(2,axis=0)) # 按行重复 [[1 2][1 2][3 4][3 4]]
print(x.repeat(2,axis=1)) # 按列重复 [[1 1 2 2][3 3 4 4]]
x = numpy.array([1,2])
print(numpy.tile(x,2)) # tile瓦片:[1 2 1 2]
print(numpy.tile(x, (2, 2))) # 指定从低维到高维依次复制的次数。
# [[1 2 1 2][1 2 1 2]]
十、随机数
numpy.random模块对Python内置的random模块进行了补充,增加了一些用于高效生成多种概率分布的样本值的函数。
例子1:
得到一个符合标准正态分布的4*4样本
samples = np.random.normal(size=(4,4))
# 打印
[[-1.24461343 -0.59702205 0.24199145 -1.91128939]
[ 0.72805342 0.46096565 0.17278008 0.92695652]
[-0.24785401 1.82771813 -0.42215406 0.27845425]
[-0.25153488 -1.71629335 0.50279265 -1.05585743]]
例子2:
比较Python内置random与NumPy模块的random运行速度
from random import normalvariate
N = 1000000
%timeit samples = [normalvariate(0, 1) for _ in xrange(N)]
# 1 loops, best of 3:1.33s per loop
%timeit np.random.normal(size=N)
# 10 loops, best of 3: 57.7ms per loop
函数 | 说明 |
---|---|
seed | 确定随机数生成器的种子 |
permutation | 返回一个序列的随机排列 |
shuffle | 对一个序列就地随机排列 |
rand | 产生均匀分布的样本值 |
randint | 给定的上下限范围内随机选取整数 |
randn | 产生正态分布(平均值为0,标准差为1)的样本值,类似于MATLAB接口 |
binomial | 产生二项分布的样本值 |
normal | 产生正态(高斯)分布的样本值 |
beta | 产生Beta分布的样本值 |
chisquare | 产生卡方分布的样本值 |
gamma | 产生Gamma分布的样本值 |
uniform | 产生在[0, 1)中均匀分布的样本值 |
更多具体函数可参考:np.random模块的使用
参考:
NumPy库的介绍与使用教程
Python之Numpy详细教程
NumPy — 从零到入门