列表转化为numpy数组

1
np1=np.array(lst)

获取数组的shape、dim、dtype等信息

1
2
3
print(np1.shape)
print(np1.ndim)
print(np1.dtype)

创建全为0的数组

1
2
np2=np.zeros((2,3,4))       # 传入元组
np3=np.zeros_like([[1,2,3],[4,5,6]]) # 传入同样形状的数组

创建全为1的数组

1
2
np4=np.ones((2,3,4))       # 传入元组
np5=np.ones_like([[1,2,3],[4,5,6]]) # 传入同样形状的数组

创建新的数组

返回的都是一些未初始化的垃圾值。

1
2
np6=np.((2,3,4))       # 传入元组
np7=np.ones_like([[1,2,3],[4,5,6]]) # 传入同样形状的数组

用指定数字填充一个数组

1
2
np8=np.full((2,3),np.inf)
np9=np.full((2,3),10)

创建对角矩阵

1
np10=np.eye(5)

numpy.eye(N, M=None, k=0, dtype=, order=’C’, *, like=None)

参数:

  • N:行数

  • M:列数,默认为N

  • k:对角线的索引,0为主对角线,正数为高对角线,负数为低对角线

数组和标量的运算

数组与标量的算术运算会将标量值传播到各个元素:

1
2
3
4
arr=np.ones((3,4))
# 下列运算都会传播到各个元素
arr1=1/arr
arr2=arr*0.5

大小相等数组的运算

大小相等的数组之间的任何算术运算都会将运算应用到元素级

1
2
3
4
arr=np.ones((3,4))
# 下列运算都会传播到各个元素
arr1=arr*arr
arr2=arr+arr

大小相同的数组之间的比较会生成布尔值数组

1
2
3
4
arr1=np.ones((3,4))
arr2=np.zeros_like(arr1)
# arr3的元素都是True
arr3=arr1>arr2

数组的索引和切片

与列表索引无异。

但是跟列表最重要的区别在于,数组切片是原始数组的视图。这意味
着**数据不会被复制,视图上的任何修改都会直接反映到源数组上。

1xN 的数组

1
2
3
4
arr = np.arange(10)
# 索引
t = arr[5]
arr1=arr[3,7]

NxN的数组

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
arr=np.ones((2,3,4))

# 索引1
arr1=arr[1][2][3]
# 索引2(与索引1等价)
arr1=arr[1,2,3]
# 切片一(注意看,消失了一个轴)
arr2=arr[1,:2,1:3]
"""
array([[1., 1.],
[1., 1.]])
"""

# 切片赋值
arr[:,:2,1:3]=2
print(arr)
"""
[[[1. 2. 2. 1.]
[1. 2. 2. 1.]
[1. 1. 1. 1.]]

[[1. 2. 2. 1.]
[1. 2. 2. 1.]
[1. 1. 1. 1.]]]
"""

布尔型索引

1
2
3
>>>arr = np.array(["A","B","C","D","A"])
>>>arr=="A"
array([ True, False, False, False, True])

布尔型索引可以应用到其他数组中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>>data=np.random.randn(5,3)
>>>data[arr=="A"]
array([[ 0.56404125, 0.16307987, -0.58351001],
[ 1.21981151, -2.82375807, 0.95452604]])
>>>data[arr=="A",2]
array([-0.58351001, 0.95452604])
>>>data[arr!="A"]
array([[-0.48488901, -0.03173889, 1.36615544],
[-0.1890298 , -1.5357594 , -1.28240933],
[-1.05119813, 0.1259434 , -0.56340036]])
>>>data[~(arr=="A")]
array([[-0.48488901, -0.03173889, 1.36615544],
[-0.1890298 , -1.5357594 , -1.28240933],
[-1.05119813, 0.1259434 , -0.56340036]])

此外,还有大于小于,多个布尔型索引可以用与或非等操作,此处不列举。

(花式索引)特定顺序切片

索引传入的时候只需要指定一个列表或者numpy数组就可以了。

使用负数索引将会从末尾开始选取行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>>arr=np.empty((8,4))
>>>for i in range(0,8):
arr[i]=i
>>>arr
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.]])

>>>arr[[3,2,6,1]] # 只需要传入一个列表或者np数组
array([[3., 3., 3., 3.],
[2., 2., 2., 2.],
[6., 6., 6., 6.],
[1., 1., 1., 1.]])

一次传入多个数组:

1
2
3
4
5
6
7
8
9
10
11
12
>>>arr = np.arange(32).reshape((8, 4))
>>>arr
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]])
>>>arr[[1, 5, 7, 2], [0, 3, 1, 2]]
array([ 4, 23, 29, 10])

牢记两点

  • 不管传入几个数组,花式索引最后一定返回一维数组

  • 多个数组传入的时候,如上例,选取的是arr[1,0]=4,arr[5,3]=23,arr[7,1]=29,arr[2,2]=10作为一维数组的元素。

浅拷贝机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
arr1=np.ones((3,4))
arr2=arr1[1,2]
arr2=9
print(arr1)
"""
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
"""


arr3=arr1[1,:2]
arr3[1]=9
print(arr1)
"""
会显示
[[1. 1. 1. 1.]
[1. 9. 1. 1.]
[1. 1. 1. 1.]]
"""

重塑和转置

1
2
3
4
5
6
7
8
9
10
11
12
13
>>>x=np.arange(24).reshape(4,6)
>>>x
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]])
>>>x.T
array([[ 0, 6, 12, 18],
[ 1, 7, 13, 19],
[ 2, 8, 14, 20],
[ 3, 9, 15, 21],
[ 4, 10, 16, 22],
[ 5, 11, 17, 23]])

transpose()方法和swapaxes方法

用于交换轴 ,详见

Python numpy.transpose 详解_numpy transpose-CSDN博客

1

通用函数

通用函数(即ufunc)是一种对ndarray中的数据执行元素级运算的函数。

单个数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>>x=np.arange(12)
>>>x.reshape(3,4)
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>>np.exp(x)
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, 8.10308393e+03, 2.20264658e+04, 5.98741417e+04])
>>>np.sqrt(x)
array([0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ,
3.16227766, 3.31662479])
>>>np.square(x)
array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121])

多个数组

1
2
3
4
5
6
7
8
9
10
11
>>>x=np.arange(6).reshape(2,3)
>>>y=np.arange(6,0,-1).reshape(2,3)
>>>np.maximum(x,y) # 两个数组对应元素的最大值
array([[6, 5, 4],
[3, 4, 5]])
>>>np.minimum(x,y) # 两个数组对应元素的最小值
array([[0, 1, 2],
[3, 2, 1]])
>>>np.add(x,y) # 两个数组对应元素相加
array([[6, 6, 6],
[6, 6, 6]])

返回多个数组

modf是Python内置函数divmod的矢量化版本,它会返回浮点数数组的小数和整数部分:

1
2
3
4
5
6
7
8
9
10
11
>>>x=np.random.randn(6).reshape((2,3))
>>>x
array([[-2.3970355 , 0.77791357, -0.77376582],
[ 0.42437037, 1.79161465, -0.20365944]])
>>>remainder, whole_part = np.modf(x)
>>>remainder
array([[-0.3970355 , 0.77791357, -0.77376582],
[ 0.42437037, 0.79161465, -0.20365944]])
>>>whole_part
array([[-2., 0., -0.],
[ 0., 1., -0.]])

一元和二元ufunf列表

矢量化方法——网格处理

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
import matplotlib.pyplot as plt

# 运用向量化方法创建网格
points=np.arange(-5,5,0.1)
xs, ys = np.meshgrid(points, points)
z=np.sqrt(xs**2+ys**2)

# 可视化
plt.imshow(z, cmap=plt.cm.gray); plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
plt.show()

如下图所示

矢量化方法——np.where

1
2
3
4
>>>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])

假设我们想要根据cond中的值选取xarr和yarr的值:当cond中的值为True时,选取xarr的值,否则取yarr的值。列表推导式的写法应该如下所示:

1
result = [(x if c else y) for x, y, c in zip(xarr, yarr, cond)]

这有几个问题。第一,它对大数组的处理速度不是很快(因为所有工作都是由纯Python完成。第二,无法用于多维数组。若使用np.where,则可以将该功能写得非常简洁:

1
result = np.where(cond, xarr, yarr)

np.where的第二个和第三个参数不必是数组,它们都可以是标量值。在数据分析工作中,where通常用于根据另一个数组而产生一个新的数组。假设有一个由随机数据组成的矩阵,你希望将所有正值替换为2,将所有负值替换为-2。若利用np.where,则会非常简单:

1
2
>>>arr = np.random.randn(4, 4)
>>>np.where(arr > 0, 2, -2)

又例:用常数2替换arr中所有正的值,负值和0不变。

1
np.where(arr > 0, 2, arr)

传递给where的数组大小可以不相等,甚至可以是标量值

数学和统计方法

均值、按轴的均值

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
>>>arr=np.random.randn(3,4)
>>>arr
array([[-0.58020959, -0.39792925, 0.81460853, 1.82152127],
[-0.46293236, 0.78065611, -0.81467171, -1.09035582],
[ 1.06016137, 0.24888008, -0.04443127, 0.13277996]])
>>>arr.mean()
np.float64(0.12233977548552276)
>>>np.mean(arr)
np.float64(0.12233977548552276)
>>>arr.mean(axis=1)
array([ 0.41449774, -0.39682595, 0.34934753])

求和、按轴的求和

1
2
3
4
5
6
7
8
9
10
11
>>>arr=np.random.randn(3,4)
>>>arr
array([[-0.58020959, -0.39792925, 0.81460853, 1.82152127],
[-0.46293236, 0.78065611, -0.81467171, -1.09035582],
[ 1.06016137, 0.24888008, -0.04443127, 0.13277996]])
>>>np.sum(arr)
np.float64(1.468077305826273)
>>>arr.sum()
np.float64(1.468077305826273)
>>>arr.sum(axis=1)
array([ 1.65799095, -1.58730378, 1.39739014])

累加函数(cumsum)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>>arr=np.arange(10)
>>>arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>arr.cumsum()
array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45])


# 按照不同的轴累加
>>>arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
>>>arr.cumsum(axis=0)
array([[ 0, 1, 2],
[ 3, 5, 7],
[ 9, 12, 15]])
>>>arr.cumsum(axis=1)
array([[ 0, 1, 3],
[ 3, 7, 12],
[ 6, 13, 21]])

用于布尔型数组的方法

在上面这些方法中,布尔值会被强制转换为1(True)和0(False)。因此,sum经常被用来对布尔数组中的true值计数

1
2
3
>>>arr = np.random.randn(100)
>>>(arr > 0).sum()
np.int64(45)

any用于测试数组中是否存在一个或多个True,而all则检查数组中所有值是否都是True:

1
2
3
4
5
>>>bools = np.array([False, False, True, False])
>>>bools.any()
True
>>>bools.all()
False

排序

用sort方法

1
2
3
4
5
6
7
8
>>>arr = np.random.randn(6)
>>>arr
array([-0.51546731, -0.69672017, -0.07422335, -0.37264409, 1.24829952,
-0.16309924])
>>>arr.sort()
>>>arr
array([-0.69672017, -0.51546731, -0.37264409, -0.16309924, -0.07422335,
1.24829952])

指定轴的排序

1
2
3
4
5
6
7
8
9
10
11
12
>>>arr=np.random.randn(12).reshape((2,6))
>>>arr
array([[-0.25665726, 0.53730452, -1.08962298, 0.39218402, 0.24570309,
1.3190456 ],
[ 0.19662659, 0.02097503, 0.29628246, 0.4907919 , 1.78748713,
0.43255797]])
>>>arr.sort(axis=0)
>>>arr
array([[-0.25665726, 0.02097503, -1.08962298, 0.39218402, 0.24570309,
0.43255797],
[ 0.19662659, 0.53730452, 0.29628246, 0.4907919 , 1.78748713,
1.3190456 ]])

集合逻辑

将一维数组转化为集合并且排序

1
2
3
4
5
6
7
8
9
10
11
>>>names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
>>>np.unique(names)
array(['Bob', 'Joe', 'Will'], dtype='<U4)


>>>arr=np.array([1,3,2,6,4,7,0,1,4])
>>>np.sort(arr)
array([0, 1, 1, 2, 3, 4, 4, 6, 7])
>>>np.unique(arr)
array([0, 1, 2, 3, 4, 6, 7])

数组文件格式(.npy)

1
2
3
4
5
6
arr=np.random.randn(144).reshape((12,12))
print('arr:',arr)
np.save("12x12_ndarry",arr) # 如果不加.npy,也可以

arr1=np.load('12x12_ndarry.npy') # 必须加.npy
print('arr1:',arr1)

线性代数

矩阵点乘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>>arr1=np.arange(12).reshape((4,3))
>>>arr2=np.arange(12).reshape((3,4))
>>>arr3=arr1.dot(arr2)
>>>arr3
array([[ 20, 23, 26, 29],
[ 56, 68, 80, 92],
[ 92, 113, 134, 155],
[128, 158, 188, 218]])
>>>arr4=np.dot(arr1,arr2)
>>>arr4
array([[ 20, 23, 26, 29],
[ 56, 68, 80, 92],
[ 92, 113, 134, 155],
[128, 158, 188, 218]])

矩阵求逆和QR值分解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>>from numpy.linalg import inv, qr
>>>a=np.random.randn(16).reshape((4,4))
>>>mat=np.dot(a,a.T)
>>>inv(mat)
array([[ 1.31306504, 0.45533194, -1.06419011, -0.9930272 ],
[ 0.45533194, 0.8722488 , -1.18740211, -0.78019301],
[-1.06419011, -1.18740211, 1.9869764 , 1.32427395],
[-0.9930272 , -0.78019301, 1.32427395, 1.22621826]])
>>>q, r = qr(mat)
>>>qr(mat)
QRResult(Q=array([[-0.56344147, 0.52661645, -0.44941887, -0.45081205],
[-0.59497181, -0.60717158, 0.38974426, -0.35419011],
[-0.36011218, -0.38380937, -0.60131472, 0.60119064],
[-0.44593886, 0.45465168, 0.53342544, 0.55667556]]), R=array([[ -5.41454513, -10.66799837, -6.30814318, -4.72356165],
[ 0. , -5.29662706, -4.8512473 , 2.23992805],
[ 0. , 0. , -2.1145548 , 2.71866387],
[ 0. , 0. , 0. , 0.45397755]]))

伪随机数生成

标准正态分布

1
2
3
4
5
6
7

>>>samples = np.random.normal(size=(4, 4))
>>>samples
array([[-0.57442398, -0.850833 , -0.21796463, -1.56780153],
[ 1.60345098, 0.11634615, -0.85471129, -1.45385702],
[-0.66995946, -0.2998366 , -1.94560696, 0.19645426],
[-1.01776318, -0.37687205, 1.54454201, 0.69070131]])

设置种子产生随机数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import matplotlib.pyplot as plt
import random

random.seed(0)
print('种子为0,random产生的随机数:',random.random())
# 0.8444218515250481

np.random.seed(0)
print('种子为0,np产生的随机数:',np.random.rand())
# 0.5488135039273248

np.random.seed(0)
print('种子为0,np产生的随机数:',np.random.rand())
# 0.5488135039273248

np.random.seed(1000)
print('种子为1000,np产生的随机数:',np.random.rand())
# 0.6535895854646095

随机漫步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
import matplotlib.pyplot as plt
import random


position = 0
walk = [position]
steps = 1000
for i in range(steps):
step = 1 if random.randint(0, 1) else -1
position += step
walk.append(position)

plt.plot(walk[:1000])
plt.show()
1

1

1