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]]