利用python进行数据分析(二)
今天咱们继续更新利用Python进行数据分析
第二部分-Python科学计算之NumPy。
参考用书:利用python进行数据分析
python版本:python3.6以上
开发环境:jupyter lab=2.2.0a1(为了适用Jupyter lab的kite插件而适用的测试版本)
NumPy
是Numerical Python的简称,是目前在Python数值计算中最为重要的包。作为Python中最重要的数组计算方式,NumPy可以对含有大量数组的数据进行高效快速操作。本文包括以下内容:
-
NumPy ndarray -
面向数组进行编程 -
使用数组进行文件输入与输出 -
线性代数
在开始之前,请确保已安装Python,可通过pip install numpy
安装NumPy包,详情可参考往期文章《从零开始学习Python-搭建Python环境》。
1.ndarray高维数组
Numpy的ndarray将一组同构数据(连续的或者跨步)解释为多维数组对象。ndarray十分灵活,得益于每个数组对象都是一个数据快的分步视图。ndarray对象包括以下内容:
-
指向数据的指针——即RAM或内存映射文件中的数据快 -
dtype——描述数组中固定大小的值的单元格(也称为元数据) -
shape——表示数组大小的元组 -
strides——表示要“步进”的字节数的整数以便沿维度推进元素
ndarray简单构造如下:
1.1 生成ndarray
array函数可以接受任意的序列型对象,生成一个新的NumPy数组。同时也可以使用数组的arange,ones,zeros,eye函数生成各类数组。
import numpy as np
data1 = [6, 7.5, 8, 5, 1]
arr1 = np.array(data1)
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 - np.array(data2)
# 查看arr2的维度和形状属性
arr2.dim
arr2.shape
其中,第一个数组的数据类型为dtype(‘float64’),第二个数组的数据类型为dtype(‘int64’)。NumPy中默认的数据类型是float64(浮点型)。
使用astype函数可以转换dtype属性,同时生成新数组 |
1.2 NumPy数组算数
在不同形状的数组进行运算时,需要用到广播机制。最简单的广播发生在将标量与数组组合:
arr = np.arange(5)
arr * 4 # 将4广播给乘法运算中的所有其他元素
更一般的情况是:将多维数组与降低一级维度数组进行运算。


广播:对于每个结尾维度(也就是从尾部开始的),轴长度都匹配或者长度都市1,广播将在丢失的或者长度为1的列上进行。通俗的讲,就是如果一个m*n的数组,碰上一个(n, 1)数组,那么广播就在行中进行。这里有个概念,就是维度必须要相同,而不能是(n, )这样的维度。在NumPy中可以通过reshape函数或者np.newaxis和完整切片来插入新轴。
arr = np.zeros((4, 4))
arr.reshape(4, 1, 4)
# 或者
arr_3d = arr[:, np.newaxis, :]
1.3 索引与切片
NumPy索引有多种方式可以选中数组子集或者单个元素。
-
基础索引
-
一维数组索引
需要注意的是:如果将数值传递给索引切片,那么数值也会传递给整个切片。数组的切片是原数组的视图,对于视图的修改都会反映到原数组,使用copy函数可以获取数组的拷贝。
arr = np.arange(10)
arr[5] # 取索引为5的元素,即第6个元素
arr[5:8] # 取索引为5到7上的元素,即第6个元素到第8个元素
arr[5:8] = 12 # arr->arr([0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
arr_slice = arr[5:8]
arr[1] = 12345 # 此时arr为 array([0, 1, 2, 3, 4, 12345, 12, 12, 8, 9]) -
二维数组
二维数组的维度可以按照以下理解:将0轴看作”行“,将1轴看作”列“。
arr2d = np.arange(10).reshape((3, 3))
arr2d[2] # 返回第三行数据
arr2d[0][2] # 等价于arr2d[0, 2],返回第一行第三列的元素每一个索引获得的数据都减少一个维度,而且选出来的子集都是视图。
-
切片索引
一维数组的切片与列表的一维对象类似。高维数组中默认沿着轴0进行切片,切片也是视图。
arr2d[:2] # 获取第一行和第二行数据
arr2d[:, 1] # 获取第二列数据 -
布尔索引
我们选用实例来描述布尔索引。
-
神奇索引
使用整数数组进行索引,但与切片不同,将数据复制到一个新的数组中。
arr = np.zeros((8, 4))
for i in range(8):
arr[i] = i
arr[[4, 3, 0, 6]] # 取出索引为4, 3, 0, 6对应行数据,并按照此顺序排列成数组
# 取出行索引为4,3,0,6、列索引为0,3,1,2对应数据,并按照此顺序排列成数组
arr[[4, 3, 0, 6], [0, 3, 1, 2]]
1.4 数据转置与换轴
转置可以返回底层数据的视图,主要有transcope方法、T属性以及swapaxes方法。
同样的,我们在jupyter lab
中操作。
2. 面向数组编程
用向量化(利用数组表达式来替代显式循环)操作数组
2.1 条件逻辑操作
使用numpy.where
来代替三元表达式x if condition else y
。
比如,将数组中大于0的数替换成2
arr = np.random.randn(4, 4)
# python列表推导式
arr_1 = np.array([2 if arr[i, j] < 0 else arr[i, j] for i in range(4) for j in range(4)]).reshape(4, 4)
# numpy.where(cond, arr1, arr2)
arr_2 = np.where(arr<0, 2, arr)
从运行时间来看,where更短;同时,对于更高维度,列表推导式也不太方便。where可以根据一个数组生成另一个新数组。
2.2 数学和统计方法
除了常规的求和(sum)、求均值(mean)、求方差/标准差(Var, std)、最值(min, max)外,还有argmin/argmax(最小/大值索引)、cumsum(累加)、cumprod(累积)。
2.3 排序
-
sort
主要有原位排序和numpy.sort排序,前者对原数组排序,后者生成副本。
-
argsort
argsort返回一个索引器,指导如何重新排列数据为指定顺序。
lexsort对多键数组执行间接字典排序。
values = np.array([5, 0, 3, 2, 1])
indexer = np.argsort(values) # array([1, 4, 3, 2, 0]) 升序对应索引值
values[indexer] # array([0, 1, 2, 3, 5])
# 用于排序数据的键从传递的最后一个数组开始,下面是从last_name开始
first_name = np.array(['Bob', 'Jane', 'Steve', 'Bill', 'Barbara'])
last_name = np.array(['Jones', 'Arnold', 'Arnold', 'Jones', 'Walters'])
sorter = np.lexsort((first_name, last_name))
zip(last_name[sorter], first_name[sorter])
3. 使用数组进行文件输入和输出
两大函数:np,save
和np.load
可以使用np.savez
将数组作为参数传递给函数,用于在未压缩文件中保存数组。再次载入时,获得字典对象。可以使用np.savez_compressed
将数据存入压缩文件。
4. 线性代数
numpy.linalg
拥有一个矩阵分解的标准函数集。常用函数如下:
函数 | 描述 |
---|---|
diag | 将方阵的对角(或非对角)元素作为一维数组返回, 或者将一维数组转换成一个方阵,并且在非对角线上有零点 |
dot | 矩阵点乘 |
trace | 计算矩阵的迹 |
det | 计算方阵的行列式 |
eig | 计算方阵的特征值和特征向量 |
inv/pinv | 计算方阵的逆矩阵/矩阵的Moore-Penrose伪逆 |
qr/svd | 计算QR分解/奇异值分解(SVD) |
solve | 求解非线性方程Ax=b,A是方阵 |
lstsq | 计算Ax=b的最小二乘解 |
总结
本文简单讲述了python中的NumPy库,可以感觉NumPy对数组型数据的强大的处理能力,以及在科学计算上的高效。在机器学习中,NumPy也大有可为,在之后的总结中,我也会继续更新关于机器学习的知识。
原文始发于微信公众号(多肉罗罗):利用Python进行数据分析
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/186409.html