「目录」
通用函数:元素级数组函数 数组表达式和矢量化 条件逻辑表达的方法 数学和统计的方法 布尔型数组的方法 数组排序的方法
利用数组进行数据处理
通用函数:元素级数组函数
通用函数可以快速对ndarray中的数据执行元素级运算。
1.一元通用函数(接受一个数组)
In [1]: import numpy as np
In [2]: arr = np.arange(10)
In [3]: arr
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.sqrt():对数组中每个元素开平方根
In [4]: np.sqrt(arr)
Out[4]:
array([0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
np.exp():对数组中每个元素求e的指数幂
In [5]: np.exp(arr)
Out[5]:
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])
np.modf():返回数组的小数部分和整数部分
In [6]: arr = np.random.randn(7) * 5
In [7]: arr
Out[7]:
array([ 0.47474019, 4.901448 , -0.47406988, 0.253216 , 5.34177144,
-2.8672812 , -2.69212577])
In [8]: remainder, whole_part = np.modf(arr)
In [9]: remainder
Out[9]:
array([ 0.47474019, 0.901448 , -0.47406988, 0.253216 , 0.34177144,
-0.8672812 , -0.69212577])
In [10]: whole_part
Out[10]: array([ 0., 4., -0., 0., 5., -2., -2.])
贴张书中的一元函数的表格
「英文版」

「中文版」


2.二元通用函数(接受两个数组)
np.maximun:x和y的元素两两比较,选出较大的元素
In [11]: x = np.random.randn(8)
In [12]: y = np.random.randn(8)
In [13]: x
Out[13]:
array([-0.67292288, 1.05053125, 0.87809133, 1.32030654, 0.93282451,
0.89897888, -0.78697472, -0.08405817])
In [14]: y
Out[14]:
array([-1.30183902, 0.45783444, 1.95733836, -0.1476115 , -0.23392697,
0.47581991, -0.20879702, -0.30709533])
In [15]: np.maximum(x, y)
Out[15]:
array([-0.67292288, 1.05053125, 1.95733836, 1.32030654, 0.93282451,
0.89897888, -0.20879702, -0.08405817])
书中二元函数的表格


数组表达式和矢量化
Numpy数组可以将很多数据处理任务表述为简洁的数组表达式。用数组表达式代替循环的方式被称为矢量化。
这样的好处有:
无需编写for循环 比等价纯python代码快上几个数量级
假设我们想要生成两组数字之间的平方根(sqrt(x^2+y^2)),可能需要两个for循环,而使用np.meshgrid函数就不需要。
np.meshgrid接受2个一维数组(坐标x和坐标y),产生2个二维矩阵。
In [11]: points = np.arange(0, 5, 1)
In [12]: xs, ys = np.meshgrid(points, points)
In [13]: xs
Out[13]:
array([[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]])
In [14]: ys
Out[14]:
array([[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]])
Note:我们用np.meshgrid生成了一个网格,xs和ys的位置是一一对应的,分别是网格上的x坐标和y坐标。

接下来直接对两个数组平方和后开根:
In [15]: z = np.sqrt(xs ** 2 + ys ** 2)
In [16]: z
Out[16]:
array([[7.07106781, 7.06400028, 7.05693985, ..., 7.04988652, 7.05693985,
7.06400028],
[7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
7.05692568],
[7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
7.04985815],
...,
[7.04988652, 7.04279774, 7.03571603, ..., 7.0286414 , 7.03571603,
7.04279774],
[7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,
7.04985815],
[7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,
7.05692568]])
用matplotlib可视化一下这个二维数组:

条件逻辑表达的方法
numpy.where是三元表达式x if condition else y 的矢量化版本,使用numpy.where可以写的更简洁和更快。
In [17]: xarr = np.array([1.1, 2.2, 1.3, 2.4, 1.5])
In [18]: yarr = np.array([2.1, 1.2, 2.3, 1.4, 2.5])
In [19]: result = np.where(xarr<yarr, xarr, yarr)
In [20]: result
Out[20]: array([1.1, 1.2, 1.3, 1.4, 1.5])
我们还可以用np.where对数组中满足条件的值进行一些操作,比如将数组中所有大于0的值替换为1,小于0的值替换为0:
In [21]: arr = np.random.randn(4, 4)
In [22]: arr
Out[22]:
array([[ 0.68090767, 0.4196389 , 0.86787669, 0.00854152],
[ 0.25991627, -0.47941677, -1.27405167, 1.18990797],
[ 1.45587956, -0.42269504, 0.07388665, -0.729446 ],
[ 1.39989266, 0.77758668, -0.65434963, -0.20764969]])
In [23]: np.where(arr>0, 1, 0)
Out[23]:
array([[1, 1, 1, 1],
[1, 0, 0, 1],
[1, 0, 1, 0],
[1, 1, 0, 0]])
数学和统计的方法
可以通过数组上的⼀组数学函数对整个数组或某个轴向的数据进行统计计算(sum、mean以及标准差std等)。
In [21]: arr = np.random.randn(5, 4)
In [22]: arr
Out[22]:
array([[ 0.74529214, -0.22833649, -1.30290025, -1.20528375],
[-0.58879565, -1.04038532, 0.91795114, 0.92261145],
[-1.70298885, 0.55620247, -1.13819377, 0.0508983 ],
[ 0.34455913, -0.38057312, -1.07086939, 0.28926554],
[ 1.01591249, 0.41953748, -1.53577132, 0.13643349]])
mean求平均或调用np.mean()
In [23]: arr.mean()
Out[23]: -0.239771713569663
In [24]: np.mean(arr)#也可以这么写
Out[24]: -0.239771713569663
sum求和或调用np.sum()
In [25]: arr.sum()
Out[25]: -4.79543427139326
可以接受⼀个axis选项参数,⽤于计算该轴向上的统计值,结果是⼀个少⼀维的数组:
In [26]: arr.mean(axis=1)
Out[26]: array([-0.49780709, 0.0528454 , -0.55852046, -0.20440446, 0.00902803])
In [27]: arr.sum(axis=0)
Out[27]: array([-0.18602074, -0.67355498, -4.12978358, 0.19392503])
Tip:arr.mean(axis=1)计算每⾏的平均值,arr.sum(axis=0)计算每列的和。
cumsum是累加函数
In [10]: arr = np.array([0, 1, 2, 3, 4, 5, 6, 7])
In [11]: arr.cumsum()
Out[11]: array([ 0, 1, 3, 6, 10, 15, 21, 28], dtype=int32)
我们来画一下0到10累加和的曲线,散点和柱状图。
arr = np.arange(10)
plt.figure(figsize=(10,8))
plt.plot(arr.cumsum(), c='black')
plt.scatter(arr, arr.cumsum(), c='red')
plt.bar(arr, arr.cumsum())

布尔型数组的方法
布尔型数组会被强制转换为1(True)和0(False)。因此使用sum可以统计布尔型数组中True的数量:
In [28]: arr = np.random.randn(100)
In [29]: (arr > 0).sum()
Out[29]: 53
any方法可以检测数组中是否存在True:
In [30]: bools = np.array([False, False, True, False, ])
In [31]: bools.any()
Out[31]: True
all方法可以检查数组中是否所有值True:
In [32]: bools.all()
Out[32]: False
数组排序的方法

排序算法的动画演示
Numpy数组也可以通过sort方法就地排序:
In [33]: arr = np.random.randn(6)
In [34]: arr
Out[34]:
array([-2.01544248, 0.54423453, 0.00532489, -0.08714192, -1.01953419,
0.91467862])
In [35]: arr.sort()
In [36]: arr
Out[36]:
array([-2.01544248, -1.01953419, -0.08714192, 0.00532489, 0.54423453,
0.91467862])
如果想要排序的副本,而不是改变原数组,则可以使用顶级方法np.sort。
arr = np.random.randn(10)*10
plt.figure(figsize=(10,8))
plt.bar(np.arange(10), arr, color='green')
plt.title('before sort')
for i in range(10):
plt.text(i, arr[i], '%.2f'%arr[i])

arr.sort()
plt.figure(figsize=(10,8))
plt.bar(np.arange(10), arr, color='green')
plt.title('after sort')
for i in range(10):
plt.text(i, arr[i], '%.2f'%arr[i])

多维数组可以在某一个维度上排序:
In [37]: arr = np.random.randn(5, 3)
In [38]: arr
Out[38]:
array([[ 1.94932447e+00, 6.69857600e-01, 1.56258242e+00],
[ 2.51426071e+00, -1.13194215e-01, 2.15159193e+00],
[-6.44137686e-01, 1.67691376e-02, 1.11240241e+00],
[ 1.89565456e-03, -6.10291402e-01, -7.69439513e-01],
[-8.50662960e-01, 6.68670854e-01, 1.56283709e-01]])
In [39]: arr.sort(1)
In [40]: arr
Out[40]:
array([[ 6.69857600e-01, 1.56258242e+00, 1.94932447e+00],
[-1.13194215e-01, 2.15159193e+00, 2.51426071e+00],
[-6.44137686e-01, 1.67691376e-02, 1.11240241e+00],
[-7.69439513e-01, -6.10291402e-01, 1.89565456e-03],
[-8.50662960e-01, 1.56283709e-01, 6.68670854e-01]])
那个画图的方法,以后笔记有。
下篇预告:线性代数。

往期回顾



Stay hungry, stay foolish
快来,点在看啦





