numpy

NumPy(Numerical Python)

在某些方面,Numpy数组与Python内置的列表类型非常相似,但是随着数组在维度上变大,Numpy数组提供了更加高效的存储和数据操作。

python中的数据类型

列表的优势是灵活,因为每个列表元素是一个包含数据和类型信息的完整结构体,而且列表可以用任意类型的数据填充。固定数据的NumPy式数组缺乏这种灵活性,但是能更有效地存储和操作数据。

python中的固定类型数组

内置的数组(array)模块可以用于创建统一类型的密集数组。

import array
L = list(range(10))
A = array.array('i',L)
array('i',[0,1,2,3,4,5,6,7,8,9])
#这里的‘i'是一个数据类型码,表示数据为整型

更实用的是Numpy包中的ndarray对象,python的数组对象提供了数组型数据的有效存储,而Numpy为该数据加上了高效的操作。

import numpy as np
np.array([1,2,3,4])
np.array([1,2,3,4],dtype='float32')
#创建一个长度为10的数组,数组的值都是0
In [59]: np.zeros(10,dtype=int)
Out[59]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
#创建一个3*5的数组,数组的值都是1
In [60]: np.ones((3,5),dtype=int)
Out[60]: 
array([[1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1]])
#创建一个3*5的数值,数组用统一的值进行填充
In [61]: np.full((3,5),3.15)
Out[61]: 
array([[3.15, 3.15, 3.15, 3.15, 3.15],
       [3.15, 3.15, 3.15, 3.15, 3.15],
       [3.15, 3.15, 3.15, 3.15, 3.15]])
#创建一个从0开始,20结束,步长为2的数组
In [62]: np.arange(0,20,2)
Out[62]: array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
#创建一个有5个元素,且元素为等差数列的数组
In [63]: np.linspace(0,1,5)
Out[63]: array([0.  , 0.25, 0.5 , 0.75, 1.  ])
#创建一个3*3,在0-1之间均匀分布的随机数组组成的数组
In [64]: np.random.random((3,3))
Out[64]: 
array([[0.51530173, 0.48086032, 0.72374332],
       [0.71859762, 0.28094784, 0.26625239],
       [0.10241742, 0.48381546, 0.49666335]])
#创建一个3*3,均值为0,方差为1的正态分布的随机数数组
In [65]: np.random.normal(0,1,(3,3))
Out[65]: 
array([[-0.12197335,  0.17629597,  1.35351424],
       [ 0.72295497,  0.98907102, -0.44402417],
       [-0.07165226, -0.02997592, -1.21310073]])
#创建一个3*3,大于等于0,小于10区间的随机整型数组
In [66]: np.random.randint(0,10,(3,3))
Out[66]: 
array([[5, 6, 6],
       [8, 8, 6],
       [4, 6, 7]])
#创建一个3*3的单位矩阵
In [69]: np.eye(3)
Out[69]: 
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
#创建一个有3个整型数组成的未初始化的数组
#数组的值是内存空间中的任意值
In [72]: np.empty(5)
Out[72]: array([0.  , 0.25, 0.5 , 0.75, 1.  ])

Numpy标准数据类型

当构建一个数组时,你可以用一个字符串参数来指定数据类型
np.zeros(10,dtype=‘int16’)

np.zeros(20,dtype=np.int16)

import numpy as np

np.random.seed(0)

x1 = np.random.randint(0,10,size=6)
x2 = np.random.randint(0,10,size=(3,4))
x3 = np.random.randint(0,10,size=(3,4,5))
print(x3.ndim)
print(x3.shape)
print(x3.size)
print(x3.dtype)

数组索引:获取单个元素
在一维数组中可以通过中括号指定索引获取第i个值(从0开始计数):

x1[0]

为了获取数组的末尾索引,可以用负值索引

x1[-1]

在多维数组中,可以用逗号分隔的索引元组获取元素:

x2[0,0]

也可以用上述方式修改元素值:
x2[0,0] = 12

数组切片:获取子数组

x[start:stop:step]
上面3个参数的默认值分别为start=0,stop=维度的大小,step=1
x[::-1]#所有的元素,逆序的
x1[:2,:3]#两行三列
x1[:,0]#获取第一列
x1[0,:]#获取第一行
x1[0]#等于x1[0,:]

关于数组切片有一点很重要也非常有用,那就是数组切片返回的是数组数据的视图,而不是数组数据的副本。这一点也是Numpy数组切片和python列表切片的不同之处。
如果修改子数组,阿么原始数组也会被修改。如果不想原始数组被修改,可以复制原始数组
x1_sub_copy = x2[:2,:2].copy()
数组变形最灵活的实现方式就是通过reshape()
reshape另一个常见的变形模式是将一个一维数组转变为二维的行或列的矩阵。
x.reshape((1,3))
array([[1,2,3]])
x[np.newaxis,:]#第二种方式

数组拼接和分裂

x1 = np.zeros(3,dtype=int)
x2 = np.ones(3,dtype=int)
x_con = np.concatenate([x1,x2])
print(x_con)
#二维数组的拼接
x3 = np.ones((3,3),dtype=int)
print(np.concatenate([x3,x3]))
#沿着固定维度处理数组
#1. 垂直栈数组
x = np.array([1,2,3])
grid = np.arange(4,10)[::-1].reshape(2,3)
v_stack = np.vstack([x,grid])
print(v_stack)

#水平栈数组
grid = np.arange(4,10)[::-1].reshape(2,3)
x = np.full(2,99)[:,np.newaxis]
h_stack = np.hstack([grid,x])
print(h_stack)
#与拼接相反的过程是分裂
#分裂可以通过np.split,np.vsplit,np.hsplit
x = np.array([1,2,3])
x1 = x.copy()[::-1]
x2 = np.full(2,99)
x_con = np.concatenate([x,x2,x1])
print(x_con)
x1,x2,x3 = np.split(x_con,[3,5])
print(x1,x2,x3)
#np.vsplit()
grid = np.arange(16).reshape((4,4))
upper,middle,lower = np.vsplit(grid,[1,3])
print(upper,middle,lower)

Numpy数组的计算:通用函数

使Numpy变快的关键是利用向量化操作,通常在Numpy的通用函数(ufunc)中实现。本节将介绍Numpy通用函数的重要性–它可以提高数组元素的重复计算的效率。
Numpy为很多类型提供了非常方便的、静态类型的、可编译程序的接口,也被称作向量操作。你可以通过简单地对数组执行操作来实现,这里对数组的操作将会用于数组中的每一个元素,这种向量方法被用于将循环推送至Numpy之下的编译层,这样会取得更快的执行效率。

print(np.arange(5)/np.arange(1,6))
x = np.arange(9).reshape((3,3))
print(2**x)

通用函数有两种存在形式:一元通用函数对单个输入操作,二元通用函数对两个输入操作。

Numpy实现的算术运算

运算符对应的通用函数描述
+np.add加法
-np.subtract减法
-np.negative负数运算
*np.multiply乘法运算
/np.divide除法运算
//np.floor_divide地板除法运算
**np.power指数运算
%np.mod模/余数

通用函数

np.absolute()
np.abs()
np.sin()
np.cos()
np.tan()
np.exp()
np.exp2()
np.power(3,x)
np.log()#以e为底
np.log2()
np.log10()
#下面两个函数对很小的输入值可以保持较好的精确度
np.expm1()
np.log1p()

如果你希望对你的数据进行一些更晦涩的数学运算,scipy.special可能包含了你需要的计算函数。

special.gamma()
...

高级的通用函数特性

  1. 指定输出
x = np.arange(5)
y = np.empty(5)
np.multiply(x,10,out=y)
print(y)
  1. 聚合
    如果我们希望用一个特定的运算reduce一个数组,那么可以用任何通用函数的reduce方法,一个reduce方法会对给定的元素和操作重复执行,直到得到单个的结果。
x = np.arange(1,6)
y = np.add.reduce(x)
z = np.multiply.reduce(x)
print(y)
print(z)
#15
#120

如果需要存储每次计算的中间结果,可以使用accumulate:

y = np.add.accumulate(x)
print(y)
#[ 1  3  6 10 15]
  1. 外积
    任何通用函数都可以用outer方法获得两个不同输入数组所有元素对的函数运算结果。
x = np.arange(1,6)
y = np.multiply.outer(x,x)
print(y)
'''
[[ 1  2  3  4  5]
 [ 2  4  6  8 10]
 [ 3  6  9 12 15]
 [ 4  8 12 16 20]
 [ 5 10 15 20 25]]
'''

聚合:最小值、最大值和其他值

#1.
y_min = min(y)
y_max = max(y)
print(y_min)
print(y_max)
#2.
y_min = y.min()
y_max = y.max()
print(y_min)
print(y_max)
#3.
y_min = np.min(y)
y_max = np.max(y)
print(y_min)
print(y_max)

#多维数组
x = np.random.random((3,4))
print(x)

y = np.empty(4)
x.min(axis=0,out=y)
print(y)
#[0.4236548  0.38344152 0.43758721 0.52889492]
#axis=0表示取得每一列的最小值,而axis=1表示取得每一行的最小值

其他聚合函数

y = np.random.random((3,4))
y[1,1] = None
print(y)
y_sum = np.sum(y)
y_sum_safe = np.nansum(y)
print(y_sum)
print(y_sum_safe)
'''
[[0.5488135  0.71518937 0.60276338 0.54488318]
 [0.4236548         nan 0.43758721 0.891773  ]
 [0.96366276 0.38344152 0.79172504 0.52889492]]
nan
6.832388677914338
'''
函数名称NaN安全版本描述
np.sumnp.nansum计算元素的和
np.prodnp.nanprod计算元素的积
np.meannp.nanmean计算元素的平均值
np.stdnp.nanstd计算元素的标准差
np.varnp.nanvar计算元素的方差
np.minnp.nanmin找出最小值
np.maxnp.nanmax找出最大值
np.argminnp.nanargmin找出最小值的索引
np.argmaxnp.nanargmax找出最大值的索引
np.mediannp.nanmedian计算元素的中位数
np.percentilenp.nanpercentile计算基于元素排序的统计值
np.anyN/A验证任何一个元素是否为真
np.allN/A验证所有元素是否为真
import seaborn
seaborn.set()#设置绘图风格

数组的计算:广播
广播用于不同大小数组的二进制通用函数的一组规则。

x = np.array([1,2,3])
sum = x+5
print(sum)
#[6 7 8]
M = np.ones((3,3))
sum = M+x
print(sum)
'''
[[2. 3. 4.]
 [2. 3. 4.]
 [2. 3. 4.]]
'''
a = np.arange(3)
b = a.copy()[:,np.newaxis]
sum = a+b
print(a)
print(b)
print(sum)
'''
[0 1 2]
[[0]
 [1]
 [2]]
[[0 1 2]
 [1 2 3]
 [2 3 4]]
'''
#归一化的操作
x = np.random.random((10,3))
x_mean = np.mean(x,axis=0) #去每一列的均值
x_centered = x - x_mean#减去这个均值实现归一化
x_centered_mean = x_centered.mean(0)#查看归一化的均值是否接近于0

比较操作

x = np.array([1,2,3,4,5])
print(x<3)
print(x>3)
print(x<=3)
print(x>=3)
print(x!=3)
print(x==3)
'''
[ True  True False False False]
[False False False  True  True]
[ True  True  True False False]
[False False  True  True  True]
[ True  True False  True  True]
[False False  True False False]
'''

比较运算符合其对应的通用函数

运算符对应的通用函数
==np.equal
!=np.not_equal
<np.less
<=np.less_equal
>np.greater
>=np.greater_equal
rng = np.random.RandomState(0)
x = rng.randint(10,size=(3,4))
print(x)
'''
[[5 0 3 3]
 [7 9 3 5]
 [2 4 7 6]]
'''
#统计布尔数组中true记录的个数
x = np.array([1,2,3,4,5])
y1 = np.count_nonzero(x<3)
y2 = np.sum(x<3)#这个可以沿着行或列进行计算
print(y1)
print(y2)

将布尔数组作为掩码

x = np.random.randint(0,10,(3,4))
print(x)
x_shulf = x<5#对数组进行判断
print(x_shulf)
x_choiced = x[x_shulf]#得到数组中所有小于5的数
print(x_choiced)

and和or判断整个对象是真或假,而&和|是指每个对象中的比特位。bin(number)将数字转换成二进制表示
and 和 or对整个对象执行单个布尔运算,而&和|对一个对象的内容(单个比特或字节)执行多个布尔运算,对于Numpy布尔数组,后者是常用的操作。

花哨的索引

rand = np.random.RandomState(0)
x = rand.randint(100,size=10)
print([x[3],x[7],x[2]])
ind = [3,7,4]#花哨
print(x[ind])

多维数组中花哨的使用
x = np.arange(12).reshape((3,4))

row = np.array([0,1,2])
col = np.array([2,1,3])
x_choiced = x[row,col]
print(x_choiced)
#[ 2  5 11]

排序
如果你想在不修改原始输入数组的基础上返回一个排好序的数组,可以使用np.sort(),如果希望用排好序的数组代替原始数组,可以使用数组的sort:x.sort()
np.argsort(x)返回的是原始数组排好序的索引值。
np.sort()也有axis参数

部分排序:分隔

x = np.array([2,3,5,1,7,4])
x_p = np.partition(x,0)#输出一个新数组,最左边是第K小的值,往右是任意顺序的其他值,这里是搜索第0个小的值。注意,这里索引也是从0开始。这个函数也有axis
print(x_p)
#k近邻
# dist_sq = np.sum((x[:,np.newaxis,:]-x[np.newaxis,:,:])**2,axis=-1)
diff = x[:,np.newaxis,:]-x[np.newaxis,:,:]
diff_diff = diff**2
dist_sq = diff_diff.sum(axis=-1)
dia = dist_sq.diagonal()
nearest = np.argsort(dist_sq)
print(nearest)
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值