数组更新
学习地址:http://www.scipy-lectures.org/
import numpy as np
1.创建数组
(1)直接创建数组
arr_1 = np.array([12,3,4,5,6])
arr_3=np.array([[[2.4,1.2,9],[5.6,32,7],[2,1,2]],[[7.6,3.2,6.7],[1,0,0],[1,1,2]],[[3,3,3],[2,1,2],[4,7,65]]])
(2)arange函数创建
np.arange(9) 得到一个1行9列的数组
Out[44]: array([0, 1, 2, 3, 4, 5, 6, 7, 8])
np.arange(1,10,2) 在[1,10)范围内,间隔为2的数组
Out[74]: array([1, 3, 5, 7, 9])
(3)random函数创建数组
1)numpy.random.randint()
官方文档中给出的用法是:numpy.random.randint(low,high=None,size=None,dtype)
生成在半开半闭区间[low,high)上离散均匀分布的整数值;若high=None,则取值区间变为[0,low)
用法及实现
high=None的情形
z = np.random.randint(6,size=(2,4))
z
Out[78]:
array([[4, 5, 1, 3],
[2, 2, 2, 2]])
2)numpy.random.randn()
官方文档中给出的用法是:numpy.random.rand(d0,d1,…dn)
以给定的形状创建一个数组,数组元素来符合标准正态分布N(0,1)
若要获得一般正态分布则可用sigma * np.random.randn(…) + mu进行表示
用法及实现:
n = np.random.randn(2,3)
n
Out[82]:
array([[-0.43622232, 0.48940263, 1.10554077],
[ 1.54972118, 0.12816391, 0.51738574]])
(3)快速创建特殊数组 np.ones,zeros,empty,identity
1)np.ones
np.ones((3,5)) 得到一个3行5列的数值都为1的数组
Out:
array([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.]])
2)np.zeros
np.zeros(5) 得到一个一行5列的数值都为0的数组
Out: array([ 0., 0., 0., 0., 0.])
3)np.empty
np.empty((2,3)) 空矩阵并不为空,认为空矩阵全为空值或者零值是不对的,空矩阵里面的元素都是返回的垃圾值。
Out:
array([[ 2.1, 3. , 5. ],
[ 6. , 7. , 8. ]])
4)np.identity
np.identity(4)
Out[44]:
array([[ 1., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 0., 1., 0.],
[ 0., 0., 0., 1.]])
(4)数组的快速转换
ones_like,empty_like,zeros_like函数
ones_like,empty_like,zeros_like后面添加的是数组,而ones,empty,zeros后面添加的是shape
结果是一样的
arr_1=np.array([3,4,5,6,7])
np.ones_like(arr_1)
Out: array([1, 1, 1, 1, 1])
2.数组的两个属性dtype和shape
dtype表示数据类型,shape表示维度大小的元祖
arr_1.dtype 不需要加括号见
Out: dtype('int32')
arr_1 = np.array([1,2.3,3],dtype=np.int32)
arr_1
Out: array([1, 2, 3]) 结果数组元素都变为了整型
arr_1.shape
Out[19]: (5,) 一维数组,有5个元素
arr_2.dtype
Out[21]: dtype('float64')
arr_2.shape
Out[22]: (3, 3, 3) 三维数字,3个元素,3行3列
(2)ones,zeros,empty与ones_like,zeros_like,empty_like函数
arange和reshape函数
1)arange函数
np.arange(9) 得到一个1行9列的数组
Out[44]: array([0, 1, 2, 3, 4, 5, 6, 7, 8])
np.arange(1,10,2) 在[1,10)范围内,间隔为2的数组
Out[74]: array([1, 3, 5, 7, 9])
2)reshap函数
t = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8])
t.reshape(3,3) 将数组t变为3行3列数组
Out:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
2.数据类型转换astype
arr_1=np.array([1,2,3,5,6])
arr_2= arr_1.astype(np.float64)
arr_2
Out[51]: array([ 1., 2., 3., 5., 6.]) 变为浮点型
Astype方法可以将数值型字符串数组直接转化数值型数组。
In [19]: numeric_strings=np.array(['12','21','33'],dtype=np.string_)
In [21]: numeric_strings.astype(np.float32)
Out[21]: array([ 12., 21., 33.], dtype=float32)
3.数组的简单运算
数组很重要,它能够使你不用编写循环语句就可以对数据执行批量操作,这一优点很重要。因此,在数据分析方面,python和R语言地位是其它语言无法替代的。
不用循环语句,直接对数据处理成可以进行批量操作的过程叫做数据矢量化。
例:
arr_1 = np.array([[1,2,3,4],[5,6,7,8]])
arr_1 **2
Out:
array([[ 1, 4, 9, 16],
[25, 36, 49, 64]], dtype=int32)
arrt_2=np.array([[1,2,3,4],[2,1,4,3]])
arrt_2 + arr_1
Out[54]:
array([[ 2, 4, 6, 8],
[ 7, 7, 11, 11]])
4.数组的索引和切片
(1)基本切片和索引
arr_1 = np.arange(10)
arr_1[2:4] 注意切片是左闭右开
Out: array([2, 3])
arr_1[5]
Out: 5
上面的切片可以重新赋值
二维的切片
In [37]: ary1=np.arange(16).reshape(4,4)
In [39]: ary1
Out[39]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [41]: ary1[:2,1:] 分为两部分,:2是第一行和第二行,1:是第1列及以后
Out[41]:
array([[1, 2, 3],
[5, 6, 7]])
小例子:选取4和11两个数字
arr = []
for i,j in ((1,0),(2,3)):
arr.append(ary1[i,j])
arr
Out[22]: [4, 11]
(2)布尔切片
1)布尔切片转换为行索引
Score=np.array([[60,65,30,76],[56,78,98,34],[55,63,76,34],[78,90,45,66],[55,89,99,70],[55,45,89,77]])
In [39]: Name=np.array(['Mr.Lin','Miss Fang','Mr.Tian','Miss Fang','Mr.Lin','Mr.Tian'])
In [40]: Name
Out[40]:
array(['Mr.Lin', 'Miss Fang', 'Mr.Tian', 'Miss Fang', 'Mr.Lin', 'Mr.Tian'],
dtype='<U9')
In [41]: Score
Out[41]:
array([[60, 65, 30, 76],
[56, 78, 98, 34],
[55, 63, 76, 34],
[78, 90, 45, 66],
[55, 89, 99, 70],
[55, 45, 89, 77]])
In [42]: Name=='Mr.Lin'
Out[42]: array([ True, False, False, False, True, False], dtype=bool)
In [44]: Score[Name=='Mr.Lin'] #这里的角码是一个布尔型列表,程序自动检索里面的bool值,自动选取“Ture”布尔值。然后把“True”布尔值转化为行号值,按行号选取数组行。选取第一行和第五行.
Out[44]:
array([[60, 65, 30, 76],
[55, 89, 99, 70]])
当然还有或,非,与的操作
Score[Name!='Miss Fang'] 选取不是Miss Fang的行,也就是选取1,3,5,6行
suoyin=(Name=='Miss Fang')|(Name=='Mr.Lin')
suoyin_1=(Name=='Miss Fang')&(Name=='Mr.Lin')
(3)Bool索引数组与切片与整数的混合使用:
注意:布尔索引不能出现在列,只能在行的位置
In [68]: Score[Name=='Mr.Lin',:3]
Out[68]:
array([[60, 65, 30],
[55, 89, 99]])
(4)花式索引
1)选取多行
array_168=np.arange(16).reshape(4,4)
In [100]: array_168[[1,3]] 注意:[1,3],由于加了中括号,所以选取的是第一行和第三行,如果没有中括号那么选取的便是1行3列.
Out[100]:
array([[ 4, 5, 6, 7],
[12, 13, 14, 15]])
2)选取多个数据
asss=np.arange(200).reshape(20,10)
In [104]: array_168[[0,1],[2,3]] 注意此时选取的是(0,2)和(1,3)的两个元素
Out[104]: array([2, 7])
3)花式索引的巧用
oparray_1=np.arange(32).reshape(8,4)
In [107]: oparray_1
Out[107]:
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 [108]: oparray_1[[1,3,5,7]][:,[0,2,3,1]] 选取1,3,5,7行,然后将列按照0,2,3,1列重新排列
Out[108]:
array([[ 4, 6, 7, 5],
[12, 14, 15, 13],
[20, 22, 23, 21],
[28, 30, 31, 29]])
In [110]: oparray_1[:,[0,2,3,1]]
Out[110]:
array([[ 0, 2, 3, 1],
[ 4, 6, 7, 5],
[ 8, 10, 11, 9],
[12, 14, 15, 13],
[16, 18, 19, 17],
[20, 22, 23, 21],
[24, 26, 27, 25],
[28, 30, 31, 29]])
(5)where和np.ix_选取数据
1)np.ix_函数
In [113]: oparray_1[np.ix_([1,3,5,7],[0,2,3,1])] 如果直接写oparray_1[[1,3,5,7],[0,2,3,1]] 则选取的是索引[1,0],[3,2],[5,3],[7,1]四个数据. 而加上np.ix_后变为1,2,5,7行与0,2,3,1列的交叉数据
Out[113]:
array([[ 4, 6, 7, 5],
[12, 14, 15, 13],
[20, 22, 23, 21],
[28, 30, 31, 29]])
2)np.where函数 np.where(condition,[x,y])
condition是判断条件,x是满足条件的数据变为x, y是不满足条件的数据变为y(注意x和y如果只给定一个的话,会报错)
Score=np.array([[60,65,30,76],[56,78,98,34],[55,63,76,34],[78,90,45,66],[55,89,99,70],[55,45,89,77]])
只给定条件参数
np.where(Score>50) 只给定条件的情况,返回的是符合条件的索引
Out[29]:
(array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5], dtype=int64),
array([0, 1, 3, 0, 1, 2, 0, 1, 2, 0, 1, 3, 0, 1, 2, 3, 0, 2, 3], dtype=int64))
np.where(Score>70,99,Score) 第三个参数写Score是不满足条件的数据,保持Score原来的数据不变
array([[60, 65, 30, 99],
[56, 99, 99, 34],
[55, 63, 99, 34],
[99, 99, 45, 66],
[55, 99, 99, 70],
[55, 45, 99, 99]])
5.数组的赋值
列表赋值
arr_1[1:5]=[6,6,6,6]
arr_1
Out[58]: array([0, 6, 6, 6, 6, 5, 6, 7, 8, 9])
数组赋值
arr_1[1:6] = np.arage([3,3,3,3,3])
arr_1
Out[63]: array([0, 3, 3, 3, 3, 3, 6, 7, 8, 9])
单元赋值
arr_1[1:6]=7 一个标量的赋值或者叫输入瞬间实现整个切片选区的赋值,这就是numpy的广播功能。数组有此功能,列表没有.
arr_1
Out[66]: array([0, 7, 7, 7, 7, 7, 6, 7, 8, 9])
列表和数组赋值的最大不同:
arr_1 = np.array([0,1,2,3,4,5,6,7,8,9])
t=arr_1[1:5]
当对t的切片进行赋值时,原数组值会改变,而如果是列表不会改变 此处很容易犯错! 此处很容易犯错! 此处很容易犯错!
t [0:3]=6
arr_1
Out[86]: array([0, 6, 6, 6, 4, 5, 6, 7, 8, 9])
所以在对数组进行操作时,记得用.copy()
arr_1 = np.array([0,1,2,3,4,5,6,7,8,9])
t=arr_1[1:5].copy()
t[0:3]=6
arr_1
Out[87]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 此时原数组的值没有改变
5.数组的交集,并集,差集
test1=np.arange(16).reshape(4,4)
test2 = np.add(test1,np.ones((4,4)))
test1[0:3,0:3]=np.array([[-3,-6,-4],[-1,2,7],[3,8,2]])
1)交集
np.intersect1d(test1,test2)
Out[13]: array([ 2., 3., 7., 8., 11., 12., 13., 14., 15.])
2)并集
np.union1d(test1,test2)
Out[14]:
array([ -6., -4., -3., -1., 1., 2., 3., 4., 5., 6., 7.,
8., 9., 10., 11., 12., 13., 14., 15., 16.])
3)差集
np.setdiff1d(test1,test2) 属于test1,但是不属于test2
Out[15]: array([-6, -4, -3, -1])
4)并集减去交集
np.setxor1d(test1,test2)
Out[16]: array([ -6., -4., -3., -1., 1., 4., 5., 6., 9., 10., 16.])