Numpy 简介
import numpy as np
Numpy是应用Python进行科学计算的基础库。它的功能包括多维数组、基本线性代数、基本统计计算、随机模拟等。Numpy的核心功能是ndarray 类,即多维数组。多维数组是线性代数中非常广泛的概念,如一维数组就是向量,二维数组是矩阵。在数组中,要求所有元素必须是同一类型,这是与列表与字典的区别之一一。针对数组,通过Numpy可以实现的基本操作包括数组的创建、数组切片、数组重组、数组运算等。01
数组的创建
常见的创建数组的方法之一:转换Python的列表、元组等数据结构为数组类型。下面实例给出了创建数组的常用命令。>>> import numpy as np # 载入Numpy库简写为"np">>> arr1 = np.array([1,2,3,4,5,6])>>> arr1array([1, 2, 3, 4, 5, 6])>>> type(arr1) # 查看数据类型numpy.ndarray>>> arr1.shape # 各个维度的数组长度(6,)>>> arr2 = np.array([[1,2,3],[4,5,6]])>>> arr2 array([[1, 2, 3], [4, 5, 6]])>>> arr2.shape(2, 3)另外,还可以利用Numpy的内置函数来直接创建数组。>>> arr3 = np.arange(0,1,0.1)>>> arr3array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])# 创建一维长度为2,二维长度为3的元素全为0的数组>>> arr4 = np.zeros((2,3)) >>> arr4 array([[ 0., 0., 0.], [ 0., 0., 0.]])# 创建一维长度为2,二维长度为3的元素全为1的二维数组>>> arr5 = np.ones((2,3)) >>> arr5array([[ 1., 1., 1.], [ 1., 1., 1.]])# 创建一维长度为2,二维长度为3的二维空数组>>> arr6 = np.empty([2,3]) >>> arr6array([[ 1., 1., 1.], [ 1., 1., 1.]]) # 从[0,1]区间的均匀分布随机抽取四个数>>> arr7 = np.random.rand(4)>>> arr7array([ 0.36570416, 0.83097711, 0.98761922, 0.87057992])# 生成一个标准正态分布的4*4样本值>>> arr8 = np.random.normal(size=(4,4)) >>> arr8array([[-0.15990639, 0.7088309 , -0.20267733, 2.14992874], [ 0.05542048, -1.15103197, 0.21129526, 0.6212253 ], [-1.31547565, 1.4401065 , 0.6680733 , -0.60608497], [-1.03471769, 0.55338916, -0.05869825, 0.61610795]])注意这里的 np.arange() 可以指定步长为(0,1)为小数,而Python内置函数range无此功能。另外,np.random 中包括多种概率分布的随机样本,是数据分析辅助的重点工具之一。02
数组的切片与索引
数组的截取与 list 相同,可以通过 [] 来指定每个维度的索引。>>> import numpy as np>>> a = np.array([[1,2,3,4,5],[6,7,8,9,10]])>>> print(a)[[ 1 2 3 4 5] [ 6 7 8 9 10]]>>> print(a[0:1]) # 截取第一行[[1 2 3 4 5]]>>> print(a[1,2:5]) # 截取第二行,第三、四、五列[ 8 9 10]>>> print(a[1:]) # 截取第二行[[ 6 7 8 9 10]]另外,在应用中经常需要返回满足给定条件的数组元素。为此,下面介绍一个按照条件索引的数组操作。>>> b = a[a>6] # 截取矩阵中大于6的元素,范围是一维数组>>> print(b)[ 7 8 9 10]03
数组重组
数组重组主要是指对原来数组进行修改,具体包括数组类型修改、数组维度修改与数组元素修改。>>> # 数组元素的数据类型为字符串>>> num_str1 = np.array(['1.2','2.4','3.6'],dtype=np.string_)>>> # 利用astype转换为浮点型>>> num_str1.astype(float)array([ 1.2, 2.4, 3.6])>>> data = np.arange(6)>>> # 利用reshape 指定新数组各个维度>>> data = data.reshape(2,3) >>> dataarray([[0, 1, 2], [3, 4, 5]])>>> # data中小于3的元素用0代替,否则用1代替>>> np.where(data < 3,0,1) array([[0, 0, 0], [1, 1, 1]])这里 np.where(condition,x,y)函数是三元表达式:满足条件(condition),输出 x ,不满足输出 y 。04
数组运算
数学中的加减乘除运算同样也使用于数组。在数组中是按照元素级进行批量运算的,下面挑选几个实例来说明这一点:>>> arr7 = np.array([[1,2,3],[4,5,6]])>>> arr7array([[1, 2, 3], [4, 5, 6]])>>> arr7 * 2 # 数组的每个每个元素都乘以2array([[ 2, 4, 6], [ 8, 10, 12]])>>> arr7*arr7 # 两个数组对应的元素进行运算array([[ 1, 4, 9], [16, 25, 36]])>>> np.log(arr7) # 数组的每个元素都取 logarray([[ 0. , 0.69314718, 1.09861229], [ 1.38629436, 1.60943791, 1.79175947]])除了上述简单的元素级运算,数组也可以进行各种矩阵运算,如矩阵向量的混合运算、矩阵求逆、矩阵行列式、矩阵特征值。>>> A = np.array([[0,1],[2,3]])>>> Aarray([[0, 1], [2, 3]])>>> v = np.array([1,2])>>> varray([1, 2])>>> v.dot(A) # dot是内积运算,运算规则与线性代数相同array([4, 7])>>> A.dot(v) # 这里v看作列变量array([2, 8])Numpy 库为Python中的数组运算提供了很多便捷,这里只列举了常用的少数几个操作命令。其实,Numpy可以看作计算科学的基础模块,而接下来介绍的pandas库是在Numpy基础上的拓展,也具备Numpy中的许多功能,而且不要求数据类型必须单一。pandas 简介
import pandas as pd
Pamdas是建立在 Numpy库之上的,是使得数据分析工作变得更简单更快的高级操作工具。pandas的进行数据处理主要针对两种数据结构:Series 和 DataFrame 。Series
Series 是建立在 pandas 库之上的,是使得数据分析工作变得更简单更快的高级操作工具。引入索引的一大作用是数据对其功能,使得进行数据处理后不会发生数据错行。最简单的 Series 可以由一个列表类型的数据生成:>>> import pandas as pd>>> ser1 = pd.Series([1,3,5,7])>>> ser10 11 32 53 7dtype: int64Series的数据变现形式:索引在左侧,值在右边,默认的索引是从0开始的整数型序列。我们也可以在创建的时候通过 index 参数指定索引数据。>>> ser2 = pd.Series([1,3,5,7], index=['a','b','c','d'])>>> ser2a 1b 3c 5d 7dtype: int64在创建 Series 后可以对它们的一些属性进行修改,如下所示:>>> ser2.indexIndex(['a', 'b', 'c', 'd'], dtype='object')>>> ser2.index = ['A','B','C','D']>>> ser2A 1B 3C 5D 7dtype: int64对 Series 中特定数据的查找,可以通过以下几种方式来实现:>>> ser2['A'] # 通过索引值查找值1>>> ser2[1] # 通过行号查找值3>>> ser2[0:2] # 通过切片来查找子序列A 1B 3dtype: int64在 Series 类型运算中,输出结果会自动对齐不同索引的数据。当序列中没有共同的索引时,则输出缺失值符号 NaN :>>> ser3 = pd.Series([1,3,5],index=['a','b','c'])>>> ser4 = pd.Series([2,4,6],index=['c','d','b'])>>> ser3 + ser4a NaNb 9.0c 7.0d NaNdtype: float64上述这种运算机制在数据处理中非常有用,按照索引来进行运算可以避免错误分行。总结:Series 基本操作类似数组和字典,它们之间可以相互转换。但是,序列是顺序指定的、具有索引的数据类型。数组是没有索引的,而字典的元素是无序的。Dataframe
DataFrame是将若干个 Series 按列合并而成的二维数据结构,每一列单独取出来就是一个 Series 。数据框 DataFrame是用于存储多行和多列的数据集合,是机器学习算法读取数据的最常用格式。就像日常见到的二维 Excel 表格一样,第一行默认表示变量名,后续每行为一个样本,而每列表示变量(特征)的取值。利用数据框之前需要导入处理数据的核心库 pandas 。下列几行代码基本包括了 DataFrame 的创建。>>> import pandas as pd # 导入 Python 库 pandas>>> dic1 = {"age":[18,20,22],"name":["xiaoming","wanghan","hanwei"],"Chinese":[90,78,97],"Math":[87,69,89],"English":[98,78,83],"History":[86,79,80],"Physics":[99,78,94]}>>> df = pd.DataFrame(dic1,index=['a','b','c'])>>> print(df) age name Chinese Math English History Physicsa 18 xiaoming 90 87 98 86 99b 20 wanghan 78 69 78 79 78c 22 hanwei 97 89 83 80 94从上面实例可以看出,数据框是由字典 data 直接转化而来。实际数据分析中,采集到的数据结构往往是多种类型的,而数据框恰好可以存放不同类型的数据。另外,利用 Python 读取的数据往往自动转化为数据框类型的,如前面介绍的读取本地数据命令 pd.read_csv() 。01
了解数据全貌
一旦把数据载入到 Python 中,首先要做的是了解数据的全貌与基本特征。例如,要知道数据框大小(行和列)、列变量名、索引号、数据类型等。如果想知道数据框的列变量与索引名称,可以使用如下命令>>> print(df.columns) # 列变量名称Index(['age', 'name', 'Chinese', 'Math', 'English', 'History', 'Physics'], dtype='object')>>> print(df.index) # 索引序列Index(['a', 'b', 'c'], dtype='object')>>> print(df.shape) # 行数与列数(3, 7)另外,Python 中存在一些内置函数可以输出许多数据框属性,例如:>>> df.info() # 整体汇总<class 'pandas.core.frame.DataFrame'>Index: 3 entries, a to cData columns (total 7 columns):age 3 non-null int64name 3 non-null objectChinese 3 non-null int64Math 3 non-null int64English 3 non-null int64History 3 non-null int64Physics 3 non-null int64dtypes: int64(6), object(1)memory usage: 168.0+ bytes>>> df.describe() # 对每一列数值型数据进行统计,包括计数、均值、标准差、标准差、各个分位数等 age Chinese ... History Physicscount 3.0 3.000000 ... 3.000000 3.000000mean 20.0 88.333333 ... 81.666667 90.333333std 2.0 9.609024 ... 3.785939 10.969655min 18.0 78.000000 ... 79.000000 78.00000025% 19.0 84.000000 ... 79.500000 86.00000050% 20.0 90.000000 ... 80.000000 94.00000075% 21.0 93.500000 ... 83.000000 96.500000max 22.0 97.000000 ... 86.000000 99.000000[8 rows x 6 columns]>>> df.describe(include=["object"]) # 基本统计描述(指定变量为类别型) namecount 3unique 3top wanghanfreq 102
访问数据
访问数据框一列与若干列的常用的方法有如下两种:>>> df["name"] # 按列变量访问a xiaomingb wanghanc hanweiName: name, dtype: object>>> df.iloc[:,3] # 按照列数访问,这里表示第二列对应的所有行a 87b 69c 89Name: Math, dtype: int64>>> df[["name","age","Math"]] # 指定列变量名 name age Matha xiaoming 18 87b wanghan 20 69c hanwei 22 89>>> df.iloc[:,:3] # 按照列数访问,这里表示前两列对应所有行 age name Chinesea 18 xiaoming 90b 20 wanghan 78c 22 hanwei 97>>> df.head() # 默认输出前五行 age name Chinese Math English History Physicsa 18 xiaoming 90 87 98 86 99b 20 wanghan 78 69 78 79 78c 22 hanwei 97 89 83 80 94>>> df.tail() # 默认输出后五行 age name Chinese Math English History Physicsa 18 xiaoming 90 87 98 86 99b 20 wanghan 78 69 78 79 78c 22 hanwei 97 89 83 80 94类似的,访问数据框的行有如下几种方法:>>> df[1:2] # 取第二行 age name Chinese Math English History Physicsb 20 wanghan 78 69 78 79 78>>> df.iloc[1,:] # 按照行数访问,这里表示第二行对应的所有列age 20name wanghanChinese 78Math 69English 78History 79Physics 78Name: b, dtype: object>>> df.iloc[0:2,] # 前两行的所有列 age name Chinese Math English History Physicsa 18 xiaoming 90 87 98 86 99b 20 wanghan 78 69 78 79 78>>> df.iloc[1,1] # 第二行第二列'wanghan'03
数字特征统计
既然数据框是个数据集合,那么我们经常需要对其进行一些基本统计描述。下面几行代码给出了常用的统计描述的操作:>>> print(df.mean()) # 默认对数值型的所有列分布求平均age 20.000000Chinese 88.333333Math 81.666667English 86.333333History 81.666667Physics 90.333333dtype: float64>>> df.sum() # 列求和,方式类似 meanage 60name xiaomingwanghanhanweiChinese 265Math 245English 259History 245Physics 271dtype: object>>> df.max() # 求最大值,求最小值用 df.min()age 22name xiaomingChinese 97Math 89English 98History 86Physics 99dtype: object>>> df.isnull() # 布尔值输出,检查每列是否有缺失值 age name Chinese Math English History Physicsa False False False False False False Falseb False False False False False False Falsec False False False False False False False>>> df['age'].unique() # 该列不同值的个数array([18, 20, 22], dtype=int64)>>> df['age'].value_counts() # 统计某一列 'age' 中各个值出现的次数18 122 120 1Name: age, dtype: int64