数组
☆创建
import numpy as np
函数,np.func()
In [38]: data = [1,2,3,4,5]
In [39]: arr1 = np.array(data)#.array()
In [40]: arr1
Out[40]: array([1, 2, 3, 4, 5])
In [41]: data2 = [2,3,4,5,6]
In [43]: arr2 = np.array([data,data2])#多维数组
In [44]: arr2
Out[44]:
array([[1, 2, 3, 4, 5],
[2, 3, 4, 5, 6]])
In [81]: arr2[0]#在一个二维数组中,各索引位置上的元素不再是标量而是一维数组
Out[81]: array([1, 2, 3, 4, 5])
In [82]: arr2[0][0]#访问元素法一
Out[82]: 1
In [83]: arr2[0,0]#访问元素法二
Out[83]: 1
In [45]: arr2.ndim#维度个数
Out[45]: 2
In [46]: arr2.dtype#数据类型
Out[46]: dtype('int64')
In [47]: np.zeros(10)#np.zeros()创建均为0的数组
Out[47]: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
In [48]: np.ones(10)#创建均为1的数组
Out[48]: array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
In [50]: np.empty(4)#创建新数组,只分配内存但不填充任何值,返回的是一些未初始化的垃圾值
Out[50]: array([6.91882394e-310, 1.92084107e-316, 5.59638180e+199, 3.77477185e-128])
In [51]: np.arange(5)#类似于python内置函数range()
Out[51]: array([0, 1, 2, 3, 4])
In [52]: n = np.array(['1.25','-9.6','42'],dtype=np.string_)#自定义数据类型
In [53]: n.astype(float)#转换数据类型
Out[53]: array([ 1.25, -9.6 , 42. ])
☆基本索引和切片
与Python列表的功能类似,但是数组切片是原始数组的视图,这意味着数据不会复制,视图上的任何修改都会直接反映到源数组上。
In [68]: arr = np.arange(10)
In [69]: arr
Out[69]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [70]: arr_slice = arr[5:8]#切片--视图--同源
In [71]: arr_slice[1] = 123
In [72]: arr#视图改变源改变
Out[72]: array([ 0, 1, 2, 3, 4, 5, 123, 7, 8, 9])
In [73]: arr_slice[:] = 64#一个值可赋给多个
In [74]: arr
Out[74]: array([ 0, 1, 2, 3, 4, 64, 64, 64, 8, 9])
In [75]: arr = np.arange(10)
In [76]: copy = arr[5:8].copy()#副本,无关
In [77]: copy[1] = 123
In [78]: arr
Out[78]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
切片索引
跟Python列表这样的一维对象差不多
In [85]: arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]])
In [86]: arr2d
Out[86]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [87]: arr2d[:2]#沿着第0轴即第一个轴切片
Out[87]:
array([[1, 2, 3],
[4, 5, 6]])
In [88]: arr2d[:2,1:]
Out[88]:
array([[2, 3],
[5, 6]])
In [89]: arr2d[1,:2]
Out[89]: array([4, 5])
In [90]: arr2d[:,:1]
Out[90]:
array([[1],
[4],
[7]])
In [91]: arr2d[:2,:1]=0#对切片表达式的赋值操作也会被扩散到整个选区+
In [92]: arr2d
Out[92]:
array([[0, 2, 3],
[0, 5, 6],
[7, 8, 9]])
布尔型索引
In [131]: data = np.random.randn(3,4)#生成3*4的正态分布的随机数据
In [132]: data
Out[132]:
array([[-1.75188112, -0.97473529, -0.92438864, -0.13394451],
[-0.7300275 , -1.18120283, 0.40682874, 1.88765587],
[-0.46677922, 0.62752763, -0.10108341, -0.39166712]])
In [124]: names = np.array(['Bob','Joe','Bob'])
In [125]: data[ names=='Bob' ]#布尔
Out[125]:
array([[-1.83015216, -0.23576058, -1.87630722, -0.57173307],
[ 0.02156803, 1.01569783, -1.77392021, -0.58198894]])
In [126]: data[names!='Bob']#否法一
Out[126]: array([[-0.55301255, -0.33224718, 0.06431646, 0.02957661]])
In [127]: data[-(names == 'Bob')]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-127-1242c1c7d3ed> in <module>()
----> 1 data[-(names == 'Bob')]
TypeError: The numpy boolean negative, the `-` operator, is not supported, use the `~` operator or the logical_not function instead.
In [128]: data[~(names == 'Bob')]#否法二
Out[128]: array([[-0.55301255, -0.33224718, 0.06431646, 0.02957661]])
In [129]: mask = (names=='Bob')|(names =='Joe') #用&和| ,Python关键字and和or在布尔型数组中无效
In [130]: data[mask]
Out[130]:
array([[-1.83015216, -0.23576058, -1.87630722, -0.57173307],
[-0.55301255, -0.33224718, 0.06431646, 0.02957661],
[ 0.02156803, 1.01569783, -1.77392021, -0.58198894]])
In [133]: data[names != 'Bob']= 10
In [134]: data
Out[134]:
array([[-1.75188112, -0.97473529, -0.92438864, -0.13394451],
[10. , 10. , 10. , 10. ],
[-0.46677922, 0.62752763, -0.10108341, -0.39166712]])
花式索引:指的是利用整数数组进行索引
跟切片不一样,总是将数据复制到新数组中
In [135]: arr = np.empty((8,4))
In [136]: for x in range(8):
...: arr[x] =x
...:
In [137]: arr
Out[137]:
array([[0., 0., 0., 0.],
[1., 1., 1., 1.],
[2., 2., 2., 2.],
[3., 3., 3., 3.],
[4., 4., 4., 4.],
[5., 5., 5., 5.],
[6., 6., 6., 6.],
[7., 7., 7., 7.]])
In [138]: arr[[4,3,5]]#选取按照自定义顺序排列,顺序用[]
Out[138]:
array([[4., 4., 4., 4.],
[3., 3., 3., 3.],
[5., 5., 5., 5.]])
In [139]: arr = np.arange(32).reshape((8,4))
#向reshape传入一个表示新形状的元组即可达到‘无需复制任何数据,数组就能从一个形状转换为另一个形状’。
#其中一维可以为负值,会根据大小自动调整
#一维到多维---reshape()
#多维到一维---reval() flatten()
In[31]:np.shape(arr)#维度
Out[31]: (8, 4)
In [140]: arr
Out[140]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31]])
In [141]: arr[[1,2,3],[1,2,3]]#(1,2),(2,2,)(3,3)
Out[141]: array([ 5, 10, 15])
In [142]: arr[[1,2,3]][:,[1,2,3]]#前面选取三行作为一个新的数组,再筛选新的数组中的三列
Out[142]:
array([[ 5, 6, 7],
[ 9, 10, 11],
[13, 14, 15]])
In [143]: arr[np.ix_([1,2,3],[1,2,3])]
#np.ix()可以将两个一维整数数组转换为一个用于选取方形区域的索引器
Out[143]:
array([[ 5, 6, 7],
[ 9, 10, 11],
[13, 14, 15]])
转置
arr.T #视图
☆通用函数ufunc
一元ufunc
np.abs(x)
np.modf(x)#将数组的小数和整数部分以两个独立数组的形式返回
二元ufunc
np.add(x,y)
np.subtract(x,y)
np.maximum(x,y)
np.minimum(x,y)
np.mod(x,y)#求余
用数组表达式代替循环的做法,通常被称为矢量化
☆将条件逻辑表述为数组运算
np.where(condition,x,y)#x if condition else y
☆数学和统计方法
基本数组统计方法
arr.sum() #经常被用来对布尔型数组中的True值计数
arr.mean()
arr.min()
arr.max()
arr.cumsum()
arr.cumprod()
bools = np.array([False,True])
bools.any()#是否至少一个为True
bools.all()#是否均为True
☆排序
In [205]: arr = np.random.randn(8)
In [206]: arr
Out[206]:
array([ 0.50564263, -1.8029587 , 0.56072006, -0.9617723 , 1.32689105,
0.18775961, -2.01358541, 0.13219525])
In [207]: np.sort(arr)#顶级方法np.sort()返回副本
Out[207]:
array([-2.01358541, -1.8029587 , -0.9617723 , 0.13219525, 0.18775961,
0.50564263, 0.56072006, 1.32689105])
In [208]: arr
Out[208]:
array([ 0.50564263, -1.8029587 , 0.56072006, -0.9617723 , 1.32689105,
0.18775961, -2.01358541, 0.13219525])
In [209]: arr.sort()#就地排序会修改数组本身
In [210]: arr
Out[210]:
array([-2.01358541, -1.8029587 , -0.9617723 , 0.13219525, 0.18775961,
0.50564263, 0.56072006, 1.32689105])
数组的集合运算
np.unique(arr)#计算arr中的唯一元素,并返回有序结果
np.intersect1d(arr1,arr2)#计算arr1&arr2的公共元素,并返回有序结果
np.union1d(arr1,arr2)#计算arr1&arr2的并集,并返回有序结果
np.in1d(x,y)#得到一个表示“x的元素是否包含于y”的布尔型数组
np.setdiff1d(x,y)#差,在x中且不在y中
np.setor1d(x,y)#集合的对称差,存在于一个数组中但不同时存在于两个数组中的元素
numpy.random模块
部分函数
np.random.seed()#种子
np.random.rand()
np.random.randn()#正态分布 In [219]: np.random.randn(3) Out[219]: array([ 0.43302619, 1.20303737, -0.96506567])
np.random.normal()#In [218]: np.random.normal(10) Out[218]: 9.825399789407058
☆数组的合并和拆分
np.concatenate([arr1,arr2],axis=1) ====np.hstack((arr1,arr2))#以面向列的方式对数组进行堆叠(沿轴1)
np.concatenate([arr1,arr2],axis=0) -====np.vstack((arr1,arr2))#以面向行的方式对数组进行堆叠(沿轴0)
np.split(arr,[x1,x2]) #x1,x2为切割位置
☆元素的重复操作
repeat#将数组中的各个元素重复一定次数
In [232]: arr = np.arange(3)
In [233]: arr
Out[233]: array([0, 1, 2])
In [234]: arr.repeat(3)
Out[234]: array([0, 0, 0, 1, 1, 1, 2, 2, 2])
In [235]: arr.repeat([1,2,3])
Out[235]: array([0, 1, 1, 2, 2, 2])
tile#沿指定轴向堆叠数组的副本
In [238]: np.tile(arr,2)
Out[238]: array([0, 1, 2, 0, 1, 2])
In [240]: np.tile(arr,(3,2))
Out[240]:
array([[0, 1, 2, 0, 1, 2],
[0, 1, 2, 0, 1, 2],
[0, 1, 2, 0, 1, 2]])
☆广播
指的是不同形状的数组之间的算术运算的执行方式。
广播的原则
如果两个数组的后缘维度(即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和(或)长度为1的维度上进行。
增加新轴
arr_1d = np.random.normal(size=3)
np.shape(arr_1d)
Out[48]: (3,)
arr1 = arr_1d[:,np.newaxis]#:复制,np.newaxis新轴
np.shape(arr1)
Out[50]: (3, 1)
arr2 = arr_1d[np.newaxis,:]
np.shape(arr2)
Out[52]: (1, 3)