Python下有很多科学计算库,这一个支点我开始学习NumPy,然后做做笔记
1、安装numpy,没花头,pip install numpy,linux记得sudo
先来对比一下效率,两个函数,一个通过python的list去做,一个通过numpy库去做,看一下计算的时间
import numpy as np
from datetime import datetime
def python_style(n: int):
l1 = [x ** 2 for x in range(n)]
l2 = [y ** 3 for y in range(n)]
ret = []
for item in range(len(l1)):
ret.append(l1[item] + l2[item])
return ret
def numpy_style(n: int):
a = np.arange(n) ** 2
b = np.arange(n) ** 3
return a + b
start = datetime.now()
py_arr = python_style(1000)
print(datetime.now() - start)
start = datetime.now()
numpy_arr = numpy_style(1000)
print(datetime.now() - start)
0:00:00.001608 ----python
0:00:00.000050 ----numpy
可以发现,巨大的差距,接下来是基础扫盲的过程。。。。。
# 创建一个numpy.ndarray类型的对象,他是一个数组
np_arr1 = np.array([[1, 2, 3], [2, 3, 4], [3, 4, 5]])
print(np_arr1) # 看下对象的内容
# [[1 2 3]
# [2 3 4]
# [3 4 5]]
print(type(np_arr1)) # 对象类型
# <class 'numpy.ndarray'>
print(np_arr1.dtype) # 中间每一个元素的类型
# int64
print(np_arr1.itemsize) # 每个元素的大小,里面每个元素都是int64,也就是8个字节
# 8
print(np_arr1.ndim) # 维度个数
# 2
print(np_arr1.shape) # 每个维度的元素个数
# (3, 3)
print(np_arr1.size) # 总元素个数,等于shape列出维度的乘积
# 9
print(np_arr1[1]) # 注意这里的[]不代表一个list而是一个numpy.ndarray容器
# [2 3 4]
print(type(np_arr1[1])) # 这个数组试一个ndarray层层叠加的过程
# <class 'numpy.ndarray'>
再来看一下简单的方法
# sharp是一个模型,确定好模型以后就可以通过模型构建数组
# def zeros(shape, dtype=None, order='C')
array = np.zeros((3, 5))
print(array)
# [[ 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0.]]
print(array.dtype) # 注意元素类型,float会有一个点'.'跟在数字后面
# float64
# 同样的还有一个
array = np.ones((3, 5))
print(array)
# [[ 1. 1. 1. 1. 1.]
# [ 1. 1. 1. 1. 1.]
# [ 1. 1. 1. 1. 1.]]
# 还有一个np.empty((3,5))这个就是创建一个模型,并不初始化,里面会有很多野数据
# arange()和range效果差不多
array = np.arange(15)
print(array)
# [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
# 多维数组也能这么创建
# array = np.array([np.arange(5), np.arange(5), np.arange(5)])
# [[0 1 2 3 4]
# [0 1 2 3 4]
# [0 1 2 3 4]]
# 通过reshape去修改重构
array = np.reshape(array, [3, 5])
print(array)
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]]
# 同样还可以扁平化
array = np.ravel(array)
print(array)
# [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
# N*N单位矩阵(eye,会有一个条对角线全为1
array = np.eye(5,5) # 第一个参数行数,第二个参数列数
print(array)
# [[ 1. 0. 0. 0. 0.]
# [ 0. 1. 0. 0. 0.]
# [ 0. 0. 1. 0. 0.]
# [ 0. 0. 0. 1. 0.]
# [ 0. 0. 0. 0. 1.]]
array = np.identity(4) # 与上面类似,只不过是个正方形
print(array)
# [[ 1. 0. 0. 0.]
# [ 0. 1. 0. 0.]
# [ 0. 0. 1. 0.]
# [ 0. 0. 0. 1.]]
数组的取值
# 以前的多维数组,我都是通过不断叠加下标去取值的,numpy就不一样了(当然你一定要这么写也是可以的)
array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(array)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
print(array[0, 1]) # 2
print(array[2, 0]) # 7
# [x,y] x代表第一个维度的第几个元素, y代表x所在维度的第几个元素
# 试一下三维
array = np.array(
[
[
[1.1, 1.2, 1.2], [2.1, 2.2, 2.3], [3.1, 3.2, 3.3]
],
[
[4.1, 4.2, 4.3], [5.1, 5.2, 5.3], [6.1, 6.2, 6.3]
],
[
[7.1, 7.2, 7.3], [8.1, 8.2, 8.3], [9.1, 9.2, 9.3]
]
])
print(array)
# [[[ 1.1 1.2 1.2]
# [ 2.1 2.2 2.3]
# [ 3.1 3.2 3.3]]
#
# [[ 4.1 4.2 4.3]
# [ 5.1 5.2 5.3]
# [ 6.1 6.2 6.3]]
#
# [[ 7.1 7.2 7.3]
# [ 8.1 8.2 8.3]
# [ 9.1 9.2 9.3]]]
print(array[0, 1, 0]) # 2.1
print(array[2, 2, 2]) # 9.3
类型转换
# 转换数据类型
# int -> float
int_array = np.arange(5)
print(int_array)
# [0 1 2 3 4]
print(int_array.dtype)
# int64
float_array = int_array.astype(np.float64) # 转换
print(float_array)
# [ 0. 1. 2. 3. 4.]
print(float_array.dtype)
# float64
# float -> int
float_array = np.arange(0, 4, 0.5)
print(float_array)
# [ 0. 0.5 1. 1.5 2. 2.5 3. 3.5]
print(float_array.astype(np.int64))
# [0 0 1 1 2 2 3 3]
# 自定义类型
# 先看一下基础类型
t = np.dtype(np.int64)
print(t.type)
print(t.char)
print(t.str)
# <class 'numpy.int64'>
# l
# <i8
# 之后在dtype参数那里就可以填入l或者<i8或者np.int64代表元素类型
# 先定义个自定义的符合类型,这里的第一个类型‘name’后面跟着两个参数,是因为字符串需要确认长度
custom_type = np.dtype([('name', np.str_, 40), ('itemnum', np.int64), ('price', np.float64)])
print(custom_type)
# [('name', '<U40'), ('itemnum', '<i8'), ('price', '<f8')]
array = np.array([
('TV',20,19.9),
('PC', 5, 99.9)
], dtype=custom_type)
print(array)
# [('TV', 20, 19.9) ('PC', 5, 99.9)]
print(array['name'])
# ['TV' 'PC']
# 数组运算
array = np.array([
[1, 2, 3],
[4, 5, 6]
])
print(array)
# [[1 2 3]
# [4 5 6]]
print(array - array)
# [[0 0 0]
# [0 0 0]]
print(array * array)
# [[ 1 4 9]
# [16 25 36]]
print(array ** 2)
# [[ 1 4 9]
# [16 25 36]]
print(1 / array)
# [[ 1. 0.5 0.33333333]
# [ 0.25 0.2 0.16666667]]
print(array // 2)
# [[0 1 1]
# [2 2 3]]
# 切片
array = np.array(
[
[
[1, 2],
[3, 4]
],
[
[5, 6],
[7, 8]
],
[
[9, 10],
[11, 12]
]
]
)
# 这是一个三维数组,那切片其实是一样的,就是需要理一下思路
print(array[:]) # 遍历三维数组内所有的二维数组
print('-------------------')
print(array[0:2]) # 遍历三维数组内前两个二维数组
print('-------------------')
print(array[-2:]) # 遍历三维数组内后两个二维数组
print('-------------------')
print(array[::-1]) # 将数组内该维度的元素反向排序,重新生成一个
# 再进一层
# 遍历三维数组的倒数两个元素,会得到两个二维数组
# 然后遍历这两个二维数组的第二个元素
print('-------------------')
print(array[-2:, 1:])
# [[[ 7 8]]
#
# [[11 12]]]
# 这个时候,再去拿那两个二维数组的第一个值
print('-------------------')
print(array[-2:, 1:, 0])
# [[ 7]
# [11]]
# 这个时候要看一下,他返回的是什么
ret_arr = array[-2:, 1:, 0]
# 他返回一个二维数组,二维数组的每一个元素都是一个只有一个元素的以为数组
print('-------------------')
print(ret_arr[1, 0]) # 11
# 每一个逗号都代表了一层维度,通过维度可以返回多个值或者一个值,返回的类型需要注意
# 测试一下取单一值的返回类型
print('-------------------')
print(array[0, 0, 0]) # 1
print(type(array[0, 0, 0])) # int64
print(array[0, ...]) # 只需要第一个维度的第0个元素
print(array[...,1] # 需要最后一个维度所有元素的第二个元素
names = np.array(['aa', 'bb', 'cc', 'dd', 'aa', 'bb', 'cc'])
data = np.random.randn(7, 4)
print(data)
# [[-0.7730927 -0.61826381 0.5954012 0.83927967]
# [ 0.17513281 -0.02061551 -0.06197476 0.87479289]
# [-0.21595191 0.15207614 -1.68710421 -2.069167 ]
# [ 0.37064103 0.50932026 0.210167 1.56221687]
# [ 0.41340528 1.445154 -1.24314649 -1.06785139]
# [ 1.43764089 1.0660907 -0.3816355 -2.27248331]
# [-0.17388653 0.14872601 -1.23795655 -0.04884237]]
print('---------------------------------------------------')
print(names == 'aa')
# [ True False False False True False False]
print(data[names == 'aa'])
# [[-0.7730927 -0.61826381 0.5954012 0.83927967]
# [ 0.41340528 1.445154 -1.24314649 -1.06785139]]
# 这个挺神奇的,将两个数组进行匹配,效果自己看一下吧
# names == 'aa' # 等于
# names != 'aa' # 不等于
# (names == 'aa') == -(names != 'aa') # 这两个是等价的
data = np.arange(7)
print(data) # [0 1 2 3 4 5 6]
print(data[(names == 'aa') | (names == 'bb')]) # [0 1 4 5]
# 接下来我们把data里所有小于4的元素赋值为666
data[data < 4] = 666
print(data) # [666 666 666 666 4 5 6]
# 花式索引
# 根据给定数组选取目标数组的元素
data = np.empty((10, 5), dtype=np.int64)
for i in range(10):
data[i] = i
print(data)
# [[0 0 0 0 0]
# [1 1 1 1 1]
# [2 2 2 2 2]
# [3 3 3 3 3]
# [4 4 4 4 4]
# [5 5 5 5 5]
# [6 6 6 6 6]
# [7 7 7 7 7]
# [8 8 8 8 8]
# [9 9 9 9 9]]
print(data[[1, 3, 4, 7, 9]])
# [[1 1 1 1 1]
# [3 3 3 3 3]
# [4 4 4 4 4]
# [7 7 7 7 7]
# [9 9 9 9 9]]
data = np.arange(32).reshape(8, 4)
print(data)
# [[ 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]]
print('--------------------------')
print(data[[1, 3, 2, 4], [0, 3, 2, 1]])
# [ 4 15 10 17] 两个数组内的元素一一对应,选取第一个维度下标为1的第0个元素。。。。。。。
print('--------------------------')
print(data[[1, 5, 7, 2]])
# [[ 4 5 6 7]
# [20 21 22 23]
# [28 29 30 31]
# [ 8 9 10 11]]
print(data[[1, 5, 7, 2]][:, [3, 2, 1]]) # 这里其实是两步
# [[ 7 6 5]
# [23 22 21]
# [31 30 29]
# [11 10 9]]
print('--------------------------')
print(data[np.ix_([0, 1], [0, 3])])
# 1.选取第一个维度第0个元素的第0个元素和第3个元素
# 2.选取第一个维度第1个元素的第0个元素和第3个元素
# [[0 3]
# [4 7]]
# 数组转置
arr = np.arange(15)
arr.reshape(3, 5)
print(arr)
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]]
print(arr.T)
# [[ 0 5 10]
# [ 1 6 11]
# [ 2 7 12]
# [ 3 8 13]
# [ 4 9 14]]
arr.shape = (3, 5) # 也可以这样直接转
print(arr)
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]]
print(arr.transpose()) # 这个也是转置
# [[ 0 5 10]
# [ 1 6 11]
# [ 2 7 12]
# [ 3 8 13]
# [ 4 9 14]]
print(arr)
# [[ 0 1 2 3 4]
# [ 5 6 7 8 9]
# [10 11 12 13 14]]
arr.resize(5,3) # 之前几个函数有的试通过返回值重新构建了一个数组,这个函数是直接改的
print(arr)
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 9 10 11]
# [12 13 14]]
其实我还有一段,先休息一下
# 数组的混合组合
data = np.arange(9).reshape(3, 3)
data2 = data * 2
print(data)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
print(data2)
# [[ 0 2 4]
# [ 6 8 10]
# [12 14 16]]
# 水平组合
print(np.hstack((data, data2)))
# [[ 0 1 2 0 2 4]
# [ 3 4 5 6 8 10]
# [ 6 7 8 12 14 16]]
# 垂直组合
print(np.vstack((data, data2)))
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 0 2 4]
# [ 6 8 10]
# [12 14 16]]
# 当axis=0的时候是垂直组合,axis=1的时候是水平组合
print(np.concatenate((data, data2), axis=0))
# [[ 0 1 2]
# [ 3 4 5]
# [ 6 7 8]
# [ 0 2 4]
# [ 6 8 10]
# [12 14 16]]
print(np.concatenate((data, data2), axis=1))
# [[ 0 1 2 0 2 4]
# [ 3 4 5 6 8 10]
# [ 6 7 8 12 14 16]]
# 深度组合
# 第一个数组的第一个元素和第二个数组的第一个元素,组成一个数组,以此类推
print(np.dstack((data, data2)))
# [[[ 0 0]
# [ 1 2]
# [ 2 4]]
#
# [[ 3 6]
# [ 4 8]
# [ 5 10]]
#
# [[ 6 12]
# [ 7 14]
# [ 8 16]]]
print('------------------------------')
data = np.arange(2)
data2 = data * 2
print(data)
# [0 1]
print(data2)
# [0 2]
print(np.column_stack((data, data2)))
# [[0 0]
# [1 2]]
print(np.dstack((data, data2)))
# [[[0 0]
# [1 2]]]
# colum_stack == dstack
print('---------------------------------')
print(np.row_stack((data, data2)))
# [[0 1]
# [0 2]]
print(np.vstack((data, data2)))
# [[0 1]
# [0 2]]
# row_stack == vstack
print('----------------------------------')
# 数组的分割
data = np.arange(1, 10).reshape(3, 3)
print(data)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
d1, d2, d3 = np.hsplit(data, 3)
print(d1)
# [[1]
# [4]
# [7]] ==> [[1] [4] [7]]
print(d2)
# [[2]
# [5]
# [8]]
print(d3)
# [[3]
# [6]
# [9]]
d1, d2, d3 = np.vsplit(data, 3)
print(d1)
# [[1 2 3]]
print(d2)
# [[4 5 6]]
print(d3)
# [[7 8 9]]
# np.split(data,3,0) == np.vsplit(data,3)
# np.split(data,3,1) == np.hsplit(data,3)
print('-----------------------------')
data = np.arange(27).reshape(3, 3, 3)
print(data)
# [[[ 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]]]
d1, d2, d3 = np.dsplit(data, 3)
print(d1)
# [
# [
# [ 0]
# [ 3]
# [ 6]
# ]
#
# [
# [ 9]
# [12]
# [15]
# ]
#
# [
# [18]
# [21]
# [24]
# ]
# ]
# 通用函数
array = np.arange(9, dtype=np.int64).reshape(3, 3)
print(array)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
# 平方
s_arr = np.square(array)
print(s_arr)
# [[ 0 1 4]
# [ 9 16 25]
# [36 49 64]]
# 平方根
print(np.sqrt(s_arr))
# [[ 0. 1. 2.]
# [ 3. 4. 5.]
# [ 6. 7. 8.]]
# e=2.718281 e的x次方
print(np.exp(array))
# [[ 1.00000000e+00 2.71828183e+00 7.38905610e+00]
# [ 2.00855369e+01 5.45981500e+01 1.48413159e+02]
# [ 4.03428793e+02 1.09663316e+03 2.98095799e+03]]
arr1 = np.arange(0, 10)
print(arr1)
# [0 1 2 3 4 5 6 7 8 9]
arr2 = np.array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
print(arr2)
# [9 8 7 6 5 4 3 2 1 0]
# 相同位置取较大的元素
print(np.maximum(arr1, arr2))
# [9 8 7 6 5 5 6 7 8 9]
# 相同位置取较小的元素
print(np.minimum(arr1, arr2))
# [0 1 2 3 4 4 3 2 1 0]
print('-------------------------')
array = np.arange(0, 2, 0.5)
print(array)
# [ 0. 0.5 1. 1.5]
# 分别返回整数和小数
arr1, arr2 = np.modf(array)
print(arr1)
# [ 0. 0.5 0. 0.5]
print(arr2)
# [ 0. 0. 1. 1.]
# 其他还有很多之后用到了,再说吧
新加几个Demo 和函数的用法
# Demo1
points = np.arange(-5, 5)
# points
# [-5 -4 -3 -2 -1 0 1 2 3 4]
xs, ys = np.meshgrid(points, points)
# xs
# [[-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]
# [-5 -4 -3 -2 -1 0 1 2 3 4]]
# ys
# [[-5 -5 -5 -5 -5 -5 -5 -5 -5 -5]
# [-4 -4 -4 -4 -4 -4 -4 -4 -4 -4]
# [-3 -3 -3 -3 -3 -3 -3 -3 -3 -3]
# [-2 -2 -2 -2 -2 -2 -2 -2 -2 -2]
# [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
# [ 0 0 0 0 0 0 0 0 0 0]
# [ 1 1 1 1 1 1 1 1 1 1]
# [ 2 2 2 2 2 2 2 2 2 2]
# [ 3 3 3 3 3 3 3 3 3 3]
# [ 4 4 4 4 4 4 4 4 4 4]]
z = np.sqrt(xs ** 2 + ys ** 2)
print(z)
plt.imshow(z, cmap=plt.cm.gray);
plt.colorbar()
plt.title("Image")
plt.show()
# Demo2
xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
print(np.where(cond, xarr, yarr))
# [ 1.1 2.2 1.3 1.4 2.5]
# Demo3
arr = np.array([[1, 2, 3], [4, 5, 6]])
# [[1 2 3]
# [4 5 6]]
# 累加 0代表列 1代表行
print(arr.cumsum(0))
# [[1 2 3]
# [5 7 9]]
print(arr.cumsum(1))
# [[ 1 3 6]
# [ 4 9 15]]
# 累乘
print(arr.cumprod(0))
# [[ 1 2 3]
# [ 4 10 18]]
print(arr.cumprod(1))
# [[ 1 2 6]
# [ 4 20 120]]