21.1 Pandas数据分析介绍
- Python在科学计算方面有很多不断改良的库,结合其在通用编程方面的强大实力,使其在数据处理、交互探索性计算以及数据可视化方面深受广大编程者的喜爱
- Python有着一个强大的科学计算生态圈,已经完全可以媲美MATLAB、 R等特定编程语言/工具
- NumPy是Python科学计算基础包,提供了以下功能(仅列举了几条)
- 快速高效的多维数组对象ndarray
- 用于对数组执行元素级计算以及直接对数组执行数学运算的函数
- 用于读写硬盘上基于数组的数据集的工具
- 线性代数运算、傅里叶变换以及随机数生成
- 用于集成由C、C++、Fortran等语言编写的代码的工具
- 对于数值型数据,NumPy数组在存储和处理数据时要比内置的Python数
据结构高效得多 - SciPy是一组专门解决科学计算中各种标准问题域的包的集合,跟NumPy的有机结合完全可以替代MATLAB的计算功能
- scipy.integrate:数值积分和微分方程求解器
- scipy.linalg:扩展了由numpy.linalg提供的线性代数和矩阵分解功能
- scipy.optimize:函数优化器以及根查找算法
- scipy.special:SPECFUN(实现了许多常用数学函数如伽玛函数的Fortran库)的包装器
- scipy.stats:标准概率分布、各种统计检验方法以及更好的描述统计法
- scipy.weave:利用内联C++代码加速数组计算的工具
- pandas提供了使我们能够快速便捷地处理结构化数据的大量数据结构和函数
- pandas兼具NumPy高性能的数组计算功能以及电子表格和关系型数据库灵活的数据处理功能
- 对于金融行业的用户,pandas提供了大量适合于金融数据的高性能时间序列功能和工具
- 学统计的人会对R语言比较熟悉,R提供的data.frame对象功能仅仅是pandas的DataFrame所提供的功能的一个子集
21.2 文件读写
- pandas提供了一些用于将表格型数据读取为DataFrame对象的函数,常用的函数为read_csv和read_table
- 函数的选项可以划分为几个大类:
- 索引:将一个或多个列当做返回的DataFrame处理,以及是否从文件、用户获取列名
- 类型推断和数据转换:包括用户定义值的转换、缺失值标记列表等
- 日期解析:包括组合功能,比如将分散在多个列中的日期时间信息组合起来
- 迭代:支持对大文件进行逐块迭代
- 不规整数据问题:跳过一些行、页脚、注释或其他一些不重要的东西
- Pandas提供了一些用于将表格型数据读取位DataFrame对象的函数。其中最常用的为read_csv和read_table。read_csv从文件、URL、文件型对象中加载带分隔符的数据。默认分隔符为逗号。read_table从文件、URL、文件型对象中加载带分隔符的数据。默认分隔符为制表符(“\t”)
- 使用read_table从文件、URL、文件型对象中加载带分隔符的数据。默认分隔符为制表符(“\t”)
- read_csv/read_table常用参数介绍:
- path :表示文件系统位置、URL、文件型对象的字符串
- sep/delimiter:用于对行中个字段进行拆分的字符序列或正则表达式
- header:用做列名的行号。默认为0(第一行),若无header行,设为None
- names:用于结果的列名列表,结合header=None
- skiprows: 需要忽略的行数
- na_values:一组用于替换NA的值
- nrows:需要读取的行数(从文件开始处算起)
- verbose:打印各种解析器信息,比如“非数值列中缺失值的数量”
- encoding:用于unicode的文本格式编码。例如,“utf-8”表示用UTF-8 编码的文本
- 在处理不规则文件时,skiprows可以帮助跳过文件中的若干行。
- 可以在读取文件时处理数据中的缺失值,要用到参数na_values。
- na_values可以接受一组表示缺失值的字符串,用字典将列的特定值指定为NaN。
- 在处理较大文件时,有两种方式:
- 通过nrows指定读取的行;
- 通过设置chunksize,逐块读取。
- 使用to_csv写出数据到文件,默认会写出行和列的标签,可以设置index和header选项进行选择。
21.3 变量离散化
- 为了便于分析,连续数据常常被离散化或拆分为“bin”。
- 要实现该功能,需要使用pandas的cut函数。pandas返回的是一个特殊的Categorical对象,可以将其看做一组表示“bin”名称的字符串。
- 实际上,它含有一个表示不同分类名称的levels数组以及一个为要划分特征数据进行标号的labels属性
- 与“区间”的数学符号一样,圆括号表示开区间,二方括号表示闭区间,
可以通过right参数修改区间。 - qcut是一个非常类似于cut的函数,它可以根据样本分位数对数据进bin划分。
- 相比cut,qcut使用样本分位数,可以得到大小基本相等的bin。
21.4 缺失值填补
- pandas使用浮点值NaN(Not a Number)表示浮点和非浮点数组中的缺失数据,它只是一个便于被检测出来的标记而已;
- Python内置的None值也会被当做NA处理
- 对于DataFrame对象,dropna默认丢弃任何含有缺失值的行,how=‘all’只丢弃全为NA的那些行,axis=1指定丢弃列
- 丢弃数据中全部为缺失值的行。
- 丢弃数据中全部为缺失值的列。
- 使用fillna方法可以填充缺失数据,并且可以增加不同的选项
- 使用字典和method方式填充,method=‘ffill’或‘bfill’(前向或后向填充),limit可以调节最大填充数量
21.5 数据标准化
- Pandas中并没有提供直接进行数据标准化的方式,可以使用scikit-learn中preprocessing的方法进行数据的标准化操作。
- 标准化有两种处理方式:Z-score标准化和min-max标准化。在一些机器学习算法中(如,支持向量机的RBF核,线性模型中的L1和L2正则化),算法要求输入的数据特征均值为0,并且方差在相同数量级。
- 这一操作可以调用preprocessing的scale方法和StandardScaler类实现。
- 在线性模型的计算过程中,要求输入数据特征在同一个数量级上,为了实现这一操作,可以调用preprocessing的MinMaxScaler方法。
21.6 数据合并
- 数据集的合并或连接运算通过一个或多个键将行连接起来,pandas中主要使用merge函数
- 默认情况下merge会将重叠列的列名当做键,可以显示地用left_on和right_on指定;连接的时候产生的是行的笛卡尔积,如下面合并结果所示有4个“b”行。
- 默认情况下,merge做的是“inner”连接,结果中的键是交集,其他方式还有“left”、“right”以及“outer”
- 有时候,DataFrame中的连接键位于其索引上,此时可以传入left_index=True或right_index=True(或两个都传)以说明索引应该被用作连接键
- 使用concat函数可以将不同的Series或DataFrame进行轴向连接;传入axis=1可以在列上进行轴向连接
- 在列上进行轴向连接得到的是基于索引外连接的结果,使用join=‘inner’可得到基于索引的内连接结果。
- 对DataFrame进行轴向连接也是同样的效果,有时候行索引是没有意义的,可以传入ignore_index=True
21.7 数据组合
- 对数据集进行分组并对各组应用一个函数,这是数据分析过程中的一个重要环节。
- 在数据集准备好之后,通常的任务就是计算分组统计或生成透视表。
- Pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片、切块、摘要等操作。
- 对数据分组并对各组应用一个函数,是数据分析工作的一个主要环节。
- Pandas中对象可以在行(axis=0)或列(axis=1)上进行分组,然后将
一个函数应用(apply)到个分组并产生一个新值。 - 最后所有这些函数的执行结果会被合并(combine)到最终结果对象中。
- Pandas中对象可以在行(axis=0)或列(axis=1)上进行分组,然后将
21.8 OneHot编码
- 在机器学习中,一种常用的分类变量转换方式为将分类变量转换为“哑变量矩阵”或“指标矩阵”。
- 如果DataFrame的某一列含有k个不同的值,则可以派生出一个k列矩阵(其值全为1或0)。pandas有一个get_dummies函数可以实现该功能。
- 有时候,你可能想给指标DataFrame的列加上一个前缀,以便能够跟其他数据进行合并。
- get_dummies的prefix参数可以实现这个功能
- 一个有用的秘诀是:结合get_dummies和诸如cut之类的离散化函数。
21.9 实验
In:
import pandas as pd
import numpy as np
In:
tipsdf = pd.read_csv("../../Course/data/tips.csv")
In:
tipsdf.head() #默认查看前5行
tipsdf.head(10)
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
In:
df2 = pd.read_table("../../Course/data/tips.csv",sep=',')
df2.tail() #默认查看后5行
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
In:
iris2 = pd.read_csv("../../Course/data/iris.data")
iris2.count() #少了一行
out:
5.1 149
3.5 149
1.4 149
0.2 149
Iris-setosa 149
dtype: int64
In:
iris3 = pd.read_csv("../../Course/data/iris.data",header=None,
names = ['a','b','c','d','e'],nrows=10,skiprows=[0])
iris3.count()
out:
a 10
b 10
c 10
d 10
e 10
dtype: int64
In:
iris3.columns = ['a','b','c','d','f'] #修改列名
In:
iris3.head()
# sepal_length,sepal_width,petal_length,petal_width,label
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
In:
# iris3.to_csv("iris3_w_ih.csv")
iris3.to_csv("iris3_w_h.csv",index=False)
In:
#描述性统计分析
# tipsdf.describe(include='all')
tipsdf.describe()
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
In:
#自定义dataframe
dic1 = {'id':[101,102],'name':['sz','gz']}
df11 = pd.DataFrame(dic1)
In:
df11.head()
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
21.9.1 数据索引
索引有三种方式:
- loc:列名
- iloc:位置
- ix:混合
In:
tipsdf.iloc[:3,1:3]
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
In:
tipsdf.loc[:4,['total_bill','sex']]
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
In:
tipsdf.values #dataframe 转ndarray
out:
array([[16.99, 1.01, 'Female', ..., 'Sun', 'Dinner', 2],
[10.34, 1.66, 'Male', ..., 'Sun', 'Dinner', 3],
[21.01, 3.5, 'Male', ..., 'Sun', 'Dinner', 3],
...,
[22.67, 2.0, 'Male', ..., 'Sat', 'Dinner', 2],
[17.82, 1.75, 'Male', ..., 'Sat', 'Dinner', 2],
[18.78, 3.0, 'Female', ..., 'Thur', 'Dinner', 2]], dtype=object)
In:
tdf1 = pd.DataFrame(np.random.randint(0,10,6).reshape(3,-1),
columns=['a','b'],index=['a','b','c'])
tdf1.head()
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
读取数据库数据
In:
import pymysql
conn = pymysql.connect(host='192.168.199.175',user='student',password='123456',
database='shanxilt',charset='utf8')
sql_cmd = "select * from teacher"
In:
teadf = pd.read_sql(sql_cmd, con=conn)
teadf.head()
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
In:
tipsdf.shape
out:
(244, 7)
In:
tipsdf.tip.value_counts()
out:
2.00 33
3.00 23
4.00 12
5.00 10
2.50 10
..
2.83 1
1.58 1
3.71 1
3.35 1
2.18 1
Name: tip, Length: 123, dtype: int64
In:
iris3.describe()
out:
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
In:
pd.qcut(iris3.a,4) #切分成4份
out:
0 (4.625, 4.9]
1 (4.625, 4.9]
2 (4.399, 4.625]
3 (4.9, 5.0]
4 (5.0, 5.4]
5 (4.399, 4.625]
6 (4.9, 5.0]
7 (4.399, 4.625]
8 (4.625, 4.9]
9 (5.0, 5.4]
Name: a, dtype: category
Categories (4, interval[float64]): [(4.399, 4.625] < (4.625, 4.9] < (4.9, 5.0] < (5.0, 5.4]]