一:Numpy
#数组和列表的效率问题,谁优谁劣
#1.循环遍历
importnumpy as npimporttime
my_arr= np.arange(1000000)
my_list= list(range(1000000))defarr_time(array):
s=time.time()for _ inarray:
_* 2e=time.time()return e -sdeflist_time(list):
s=time.time()for _ inlist:
_* 2e=time.time()return e -s
ret1=arr_time(my_arr)print("数组运行的时间是{}".format(ret1))
ret2=list_time(my_list)print("列表运行的时间是{}".format(ret2))#结果
数组运行的时间是0.2110121250152588 # 遍历,列表快列表运行的时间是0.04800271987915039
#2.自身扩容
importnumpy as npimporttime
my_arr= np.arange(1000000)
my_list= list(range(1000000))defarr_time(array):
s=time.time()for _ in range(10):
array* 2e=time.time()return e -sdeflist_time(list):
s=time.time()for _ in range(10):
list* 2e=time.time()return e -s
ret1=arr_time(my_arr)print("数组运行的时间是{}".format(ret1))
ret2=list_time(my_list)print("列表运行的时间是{}".format(ret2))#结果
数组运行的时间是0.018001317977905273 # 扩容,数组快列表运行的时间是0.2950167655944824
numpy处理数据快的原因是:在一个连续的内存块中取存取数据。
1. numpy中的ndarray:一种多维的数组对象,是一种快速灵活的大数据容器。
创建ndarray:数组的创建最简单的办法就是使用array函数,它接收一切序列型的对象,其中也包括数组。
data = [1,2,3,4,5]
arr1=np.array(data)print(arr1)#[1,2,3,4,5] 将python的列表,转成数组
data = [[1,2,3,4,5],[6,7,8,9,10]]
arr2=np.array(data)print(arr2)
[[1 2 3 4 5]
[6 7 8 9 10]]
查看数组的维度和形状
w1 =arr1.ndim # 维度
s1=arr1.shape # 形状
w2=arr2.ndim
s2=arr2.shapeprint("数组arr1的维度是{},形状是{}".format(w1,s1))print("数组arr2的维度是{},形状是{}".format(w2,s2))数组arr1的维度是1,形状是(5,)
数组arr2的维度是2,形状是(2, 5)
其他形式的创建数组
np.zeros(20)#结果
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0.])
np.zeros((3,6))
# 结果
array([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
np.ones(10)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
np.ones((3,6))
array([[1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1.]])
np.arrange(10)是python中range的数组版本
np.arange(10)#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2 numpy中的ndarray的数据类型
创建时候指定数据类型
data = [1,2,3,4,5]
arr3= np.array(data,dtype=np.float64)print(arr3.dtype)#float64
数组数据类型转换
data = [1,2,3,4,5]
arr4=np.array(data)print(arr4.dtype)#int32
float_arr4 =arr4.astype(np.float64)print(float_arr4.dtype)#float64
注意:浮点型,转为整形,小数点后面的数组,自动去除,类型与python中的取整。
data = [1.1,2,1,3,1,4,1]
arr5=np.array(data)print(arr5.dtype)
int_arr5=arr5.astype(np.int32)print(int_arr5.dtype)#
float64
int32print(int_arr5)#[1 2 1 3 1 4 1]
注意:astype可以将某些全是数值类型的字符串转成数值形式 str = "123456"
demo = ["1","2","3"]
demo_str=np.array(data)
new_demo=demo_str.astype(float)
new_demo#array([1.1, 2. , 1. , 3. , 1. , 4. , 1. ]) # 结果很奇怪
二:numpy数组的运算
加减乘除
arr6 = np.array([[1,2,3,4,5],[6,7,8,9,10]])
arr6#结果
array([[ 1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]])
arr6+arr6#结果
array([[ 2, 4, 6, 8, 10],
[12, 14, 16, 18, 20]])
arr6-arr6#结果
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
arr6*arr6#结果
array([[ 1, 4, 9, 16, 25],
[36, 49, 64, 81, 100]])1 /arr6#结果
array([[1. , 0.5 , 0.33333333, 0.25 , 0.2],
[0.16666667, 0.14285714, 0.125 , 0.11111111, 0.1 ]])
数组之间的比值,产生布尔数组
arr6
array([[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]])
arr7= np.array([[5,4,1,2,3],[6,8,10,9,7]])
arr7
array([[5, 4, 1, 2, 3],
[6, 8, 10, 9, 7]])
arr6>arr7#结果
array([[False, False, True, True, True],
[False, False, False, False, True]])
# 数组与常量进行加减乘除,或者数组之间的比较,叫做广播
切片和索引
一维数组的切片和索引
#一维数组的索引和切片 非常类似于python列表的操作
arr1 = np.arange(10)
arr1
array([0,1, 2, 3, 4, 5, 6, 7, 8, 9])
arr1[0]
0
arr1[0:-1]
array([0,1, 2, 3, 4, 5, 6, 7, 8])
注意:不同于列表的地方是:
arr1[:] =0 # 可以对切片进行改值,将范围内的所有元素改成统一值
arr1
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
arr_slice = arr1[1:3]
arr_slice
array([0, 0])
arr_slice[0]= 1 # 切片不是python字典中的浅拷贝,切片后的元素也是映射到源数组,因此改变切片的内容,也会影响源数组的内容arr1
array([0,1, 0, 0, 0, 0, 0, 0, 0, 0])
注意:虽然会影响到源数组,通过复制切片,再进行修改就不会影响到源数组。
arr_slice2 = arr1[1:3].copy()
arr_slice2
array([1, 0])
arr_slice2[0]= 100arr1
array([0,1, 0, 0, 0, 0, 0, 0, 0, 0])
高维数组的切片和索引:高维数组的索引,不在是数,而是一个数组
二维数组
arr2 = np.array([[1,3],[2,4]])
arr2
array([[1, 3],
[2, 4]])
arr2[0]
array([1, 3])
arr2[1]
array([2, 4])
arr2[1][0]
2
arr2[1][1]
4
三维数组
arr3 = np.array([[[1,2,1],[3,4,3],[5,6,5]]])
arr3
array([[[1, 2, 1],
[3, 4, 3],
[5, 6, 5]]])
arr3[0]
array([[1, 2, 1],
[3, 4, 3],
[5, 6, 5]])
arr3[1]---------------------------------------------------------------------------IndexError Traceback (most recent call last) in
----> 1 arr3[1]
IndexError: index1 is out of bounds for axis 0 with size 1
#因为arr3不是这种结构[[ [],[],[] ],[ [],[],[] ],[ [],[],[] ],[ [],[],[] ]]
arr3[0] 只能取,第一个二维索引,arr3中也只有一个二维索引,1会越界。
注意:arr3[0] 可以用标量和数组进行赋值
arr3[0] = 1arr3
array([[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]])
arr3[0] =[[0,0,0],[0,0,0],[0,0,0]]
arr3
array([[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]])
注意:三维数组的连续索引
arr3[0][1]
array([0, 0, 0])
arr3[0,1] # 等价于上面一个
array([0, 0, 0])
二维数组的切片
arr = np.array([[1,2,3],[4,5,6],[7,8,9],[9,8,7],[6,5,4],[3,2,1]])
arr
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[9, 8, 7],
[6, 5, 4],
[3, 2, 1]])
arr[:3] #这种形式的切片是按照x,也就是行,进行切片的。
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
arr = np.array([[1,2,3],[4,5,6],[7,8,9],[9,8,7],[6,5,4],[3,2,1]])
arr
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[9, 8, 7],
[6, 5, 4],
[3, 2, 1]])
arr[:3]
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])#连续按照x轴,即行进行切,第二次切是对每一个一维数组进行切片。
arr[:3,1:]
array([[2, 3