numpy基础--利用数组进行数据处理
以下代码的前提:import numpy as np
numpy数组可以将许多种数据处理任务表述为简洁的数组表达式,用数组表达式替换循环的做法,通常被称为矢量化。
官方说明文档:Array creation routines — NumPy v1.21 Manual
例如:我们想要处理一组值(网格型)上计算函数sqrt(x^2 + y^2)。np.meshgrid函数接受两个一维数组,并产生两个二维矩阵(对应于两个数组中所有的(x, y)对)。
1 >>> a = np.array([1, 2, 3])
2 >>> b = np.array([4, 5, 6])
3 >>> ax, bx = np.meshgrid(a, b)
4 >>> ax
5 array([[1, 2, 3],
6 [1, 2, 3],
7 [1, 2, 3]])
8 >>> bx
9 array([[4, 4, 4],
10 [5, 5, 5],
11 [6, 6, 6]])
>>> z = np.sqrt(ax**2 + bx**2)
>>> z
array([[4.12310563, 4.47213595, 5. ],
[5.09901951, 5.38516481, 5.83095189],
[6.08276253, 6.32455532, 6.70820393]])
1.1 将条件逻辑表述为数组运算
numpy.where函数得三元表达式x if condition else y的矢量化版本。
numpy.where(condition[, x, y])
Return elements chosen from x or y depending on condition.
官方文档:numpy.where — NumPy v1.21 Manual
1 >>> xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
2 >>> yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
3 >>> cond = np.array([True, False, True, True, False])
4 >>> result = np.where(cond, xarr, yarr) #当cond中的值为True时,选取xarr的值,否则选取yarr
5 >>> result
6 array([1.1, 2.2, 1.3, 1.4, 2.5])
np.where的第二个和第三个参数不必是数组,它们都可以是标量值。在数据分析工作中,where通常用于根据另一个数组而产生一个新的数组。
1 >>> arr = np.random.randn(4, 4)
2 >>> arr
3 array([[-0.93788349, -0.13896424, -0.36149471, 0.55366473],
4 [-1.36781828, -1.09133439, -0.95340544, 1.58276544],
5 [ 0.55284577, 2.40035295, -0.53861131, -1.38135074],
6 [-0.23264662, 0.03819103, -0.2086907 , 2.32634099]])
7 >>> np.where(arr > 0, 2, -2) #将正值设为2,负值设为-2
8 array([[-2, -2, -2, 2],
9 [-2, -2, -2, 2],
10 [ 2, 2, -2, -2],
11 [-2, 2, -2, 2]])
12 >>> np.where(arr > 0, 2, arr) #只将正值设置为2
13 array([[-0.93788349, -0.13896424, -0.36149471, 2. ],
14 [-1.36781828, -1.09133439, -0.95340544, 2. ],
15 [ 2. , 2. , -0.53861131, -1.38135074],
16 [-0.23264662, 2. , -0.2086907 , 2. ]])
1.2 数学和统计方法
可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计计算。sum、mean以及标准差std等聚合计算(aggregation,通常叫做约简(reduction))既可以当作数组的实例方法调用,也可以当作顶级numpy函数的使用。
mean和sum这类函数可以接受一个axis参数(用于计算该轴向上的统计值),最终计算的结果是一个少一维的数组。这里说的轴的意思如下:
mean官方说明:numpy.mean — NumPy v1.21 Manual
sum官方说明:numpy.sum — NumPy v1.21 Manual
std官方说明:numpy.std — NumPy v1.21 Manual
1 >>> arr = np.arange(8).reshape(2, 4)
2 >>> arr
3 array([[0, 1, 2, 3],
4 [4, 5, 6, 7]])
5 >>> arr.mean()
6 3.5
7 >>> np.mean(arr)
8 3.5
9 >>> arr.sum()
10 28
11 >>> arr.sum(0)
12 array([ 4, 6, 8, 10])
13 >>> arr.mean(0)
14 array([2., 3., 4., 5.])
15 >>> arr.sum(1)
16 array([ 6, 22])
17 >>> arr.mean(1)
18 array([1.5, 5.5])
19 >>> arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
20 >>> arr.cumsum(0)
21 array([[ 0, 1, 2],
22 [ 3, 5, 7],
23 [ 9, 12, 15]], dtype=int32)
24 >>> arr.cumprod(0)
25 array([[ 0, 1, 2],
26 [ 0, 4, 10],
27 [ 0, 28, 80]], dtype=int32)
28 >>>
基本数组统计方法:
方法 | 说明 |
---|---|
sum | 对数组中全部或某轴向的元素求和,零长度的数组的sum为0 |
mean | 算术平均值,零长度的数组的mean为NaN |
std、var | 分别为标准差和反差,自由度可调(默认为n) |
min、max | 最大值和最小值 |
argmin、argmax | 分别为最大和最小元素的索引 |
cumsum | 所有元素的累计和,如果没有指定坐标,则当作一维数组处理。 |
cumprod | 所有元素的累计积,如果没有指定坐标,则当作一维数组处理。 |
1.3 用于布尔型数组的方法
在上表中的方法中,布尔值会被强制转换为1(True)和False(0)。因此sum经常被用来对布尔型数组中的True值计数。另外any可用于测试数组中是否存在一个或多个True,而all则检查数组中所有值是否都是True。
1 >>> arr = np.random.randn(100)
2 >>> (arr > 0).sum()
3 52
4 >>> bools = np.array([False, False, True, False])
5 >>> bools.any()
6 True
7 >>> bools.all()
8 False
9 >>>
1.4 排序
numpy数组也可以通过sort方法就地排序,多维数组可以在任何一个轴向上进行排序,只需将轴编号传给sort即可。
1 >>> arr = np.random.randn(8)
2 >>> arr
3 array([ 1.63629002, 2.20429024, -0.14614928, -0.29397459, -2.45375594,
4 1.14484692, -0.28331352, 0.30005863])
5 >>> arr.sort()
6 >>> arr
7 array([-2.45375594, -0.29397459, -0.28331352, -0.14614928, 0.30005863,
8 1.14484692, 1.63629002, 2.20429024])
9 >>> arr = np.random.randn(5, 3)
10 >>> arr
11 array([[-0.94707326, -0.21398683, 1.34561267],
12 [ 0.82759518, -1.49443648, 0.5760489 ],
13 [ 1.22341129, 0.55710449, 0.27911583],
14 [ 0.25850697, -0.15072134, -0.40032061],
15 [-1.70822177, 0.89374659, 0.13256954]])
16 >>> arr.sort(0)
17 >>> arr
18 array([[-1.70822177, -1.49443648, -0.40032061],
19 [-0.94707326, -0.21398683, 0.13256954],
20 [ 0.25850697, -0.15072134, 0.27911583],
21 [ 0.82759518, 0.55710449, 0.5760489 ],
22 [ 1.22341129, 0.89374659, 1.34561267]])
23 >>>
1.5 唯一化以及其他的集合逻辑
numpy提供了一些针对一维ndarray的基本集合运算,最常用的是np.unique,用于找出数组中唯一值并返回已排序的结果。
np.in1d函数可用于测试一个数组中的值在另一个数组中的成员资格,返回一个布尔型数组。
1 >>> names = np.array(['bob', 'joe', 'will', 'bob', 'will', 'joe', 'joe'])
2 >>> np.unique(names)
3 array(['bob', 'joe', 'will'], dtype='<U4')
4 >>> ints = np.array([3, 3, 2, 1, 4, 5])
5 >>> np.unique(ints)
6 array([1, 2, 3, 4, 5])
7 >>> sorted(set(names))
8 ['bob', 'joe', 'will']
9 >>> values = np.array([6, 0, 0, 3, 2, 2, 5, 6])
10 >>> np.in1d(values, [2, 3, 6])
11 array([ True, False, False, True, True, True, False, True])
12 >>>
下表是数组的集合运算。
方法 | 说明 |
---|---|
unique(x) | 计算x中的唯一元素,并返回有序结果 |
intersect1d(x, y) | 计算x和y中的公共元素,并返回有序结果 |
union1d(x, y) | 计算x和y的并集,并返回有序结果 |
in1d(x, y) | 得到一个表示“x的元素是否包含于y”的布尔型数组 |
setdiff1d(x, y) | 集合的差,即元素在x中且不在y中 |
setxor1d(x, y) | 集合的对称差,即存在于一个数组中但不同时存在于两个数组中的元素。 |
>>> x = np.array([1, 2, 3])
>>> y = np.array([2, 3, 4, 5])
>>> np.intersect1d(x, y)
array([2, 3])
>>> np.union1d(x, y)
array([1, 2, 3, 4, 5])
>>> np.setdiff1d (x, y)
array([1])
>>> np.setxor1d(x, y)
array([1, 4, 5])