《数据分析实战 45 讲》 学习笔记 Day1

130 阅读4分钟

04用numpy快速处理数据

使用 NumPy 让你的 Python 科学计算更高效

为什么要用 NumPy 数组结构而不是 Python 本身的列表 list?这是因为列表 list 的元素在系统内存中是分散存储的,而 NumPy 数组存储在一个均匀连续的内存块中。这样数组计算遍历所有的元素,不像列表 list 还需要对内存地址进行查找,从而节省了计算资源。另外在内存访问模式中,缓存会直接把字节块从 RAM 加载到 CPU 寄存器中。因为数据连续的存储在内存中,NumPy 直接利用现代 CPU 的矢量化指令计算,加载寄存器中的多个连续浮点数。另外 NumPy 中的矩阵计算可以采用多线程的方式,充分利用多核 CPU 计算资源,大大提升了计算效率。当然除了使用 NumPy 外,你还需要一些技巧来提升内存和提高计算资源的利用率。一个重要的规则就是:避免采用隐式拷贝,而是采用就地操作的方式。举个例子,如果我想让一个数值 x 是原来的两倍,可以直接写成 x*=2,而不要写成 y=x*2。

这样速度能快到 2 倍甚至更多。既然 NumPy 这么厉害,你该从哪儿入手学习呢?在 NumPy 里有两个重要的对象:ndarray(N-dimensional array object)解决了多维数组问题,而 ufunc(universal function object)则是解决对数组进行处理的函数。下面,我就带你一一来看。
ndarray
对象ndarray 实际上是多维数组的含义。在 NumPy 数组中,维数称为秩(rank),一维数组的秩为 1,二维数组的秩为 2,以此类推。在 NumPy 中,每一个线性的数组称为一个轴(axes),其实秩就是描述轴的数量。
ufunc
运算ufunc 是 universal function 的缩写,是不是听起来就感觉功能非常强大?确如其名,它能对数组中每个元素进行函数操作。NumPy 中很多 ufunc 函数计算速度非常快,因为都是采用 C 语言实现的。
算数
运算通过 NumPy 可以自由地创建等差数组,同时也可以进行加、减、乘、除、求 n 次方和取余数。 统计函数
如果你想要对一堆数据有更清晰的认识,就需要对这些数据进行描述性的统计分析,比如了解这些数据中的最大值、最小值、平均值,是否符合正态分布,方差、标准差多少等等。它们可以让你更清楚地对这组数据有认知。下面我来介绍下在 NumPy 中如何使用这些统计函数。
计数组 / 矩阵中的最大值函数 amax(),最小值函数 amin()
统计最大值与最小值之差 ptp()
统计数组的百分位数 percentile()
统计数组中的中位数 median()、平均数 mean()
统计数组中的加权平均值 average()
统计数组中的标准差 std()、方差 var()

NumPy 排序
这里你可以使用 sort 函数,sort(a, axis=-1, kind=‘quicksort’, order=None),默认情况下使用的是快速排序;在 kind 里,可以指定 quicksort、mergesort、heapsort 分别表示快速排序、合并排序、堆排序。同样 axis 默认是 -1,即沿着数组的最后一个轴进行排序,也可以取不同的 axis 轴,或者 axis=None 代表采用扁平化的方式作为一个向量进行排序。另外 order 字段,对于结构化的数组可以指定按照某个字段进行排序。

练习题:统计全班的成绩假设一个团队里有 5 名学员,成绩如下表所示。你可以用 NumPy 统计下这些人在语文、英语、数学中的平均成绩、最小成绩、最大成绩、方差、标准差。然后把这些人的总成绩排序,得出名次进行成绩输出。

image.png 解答代码:
import numpy as np ''' 假设一个团队里有5名学员,成绩如下表所示。 1.用NumPy统计下这些人在语文、英语、数学中的平均成绩、最小成绩、最大成绩、方差、标准差。 2.总成绩排序,得出名次进行成绩输出。 ''' scoretype = np.dtype({ 'names': ['name', 'chinese', 'english', 'math'], 'formats': ['S32', 'i', 'i', 'i']}) peoples = np.array( [ ("zhangfei", 66, 65, 30), ("guanyu", 95, 85, 98), ("zhaoyun", 93, 92, 96), ("huangzhong", 90, 88, 77), ("dianwei", 80, 90, 90) ], dtype=scoretype) #print(peoples) name = peoples[:]['name'] wuli = peoples[:]['chinese'] zhili = peoples[:]['english'] tili = peoples[:]['math'] def show(name,cj): print name, print " |", print np.mean(cj), print " | ", print np.min(cj), print " | ", print np.max(cj), print " | ", print np.var(cj), print " | ", print np.std(cj) print("科目 | 平均成绩 | 最小成绩 | 最大成绩 | 方差 | 标准差") show("语文", wuli) show("英语", zhili) show("数学", tili) print("排名:") ranking =sorted(peoples,cmp = lambda x,y: cmp(x[1]+x[2]+x[3],y[1]+y[2]+y[3]), reverse=True) print(ranking)