基础

〇概述

本文章是基于anaconda中notebook的python语言,其中涉及到众多python库,包括不限于NumPy,Pandas,Matplotlib,Seaborn,Bokeh,jieba,nltk等,软件相关具体插件请到Anaconda官网下载

注意:本文章主要是一个总结整理,因为不太会利用这种方式编辑,所以可读性非常差,若是真心学习,请移步至相关文档。

# I数据分析的流程

1.需求分析

        需求分析一词来源于产品设计,主要是指从用户提出的需求出发,挖掘用户内心的真实意图,并转化为产品需求的过程。
        数据分析中的需求分析是数据分析环节的第一步,也是非常重要的一步,决定了后续的分析方向和方法。
        数据分析中的需求分析的主要内容是,根据业务、生产和财务等部门的需要,结合现有的数据情况,提出数据分析需求的整体分析方向、分析内容,最终和需求方达成一致意见。

2. 数据获取

        数据获取是数据分析工作的基础,是指根据需求分析的结果提取、收集数据。
        数据获取主要有两种方式:
            网络数据是指存储在互联网中的各类视频、图片、语音和文字等信息。本地数据则是指存储在本地数据库中的生产、营销和财务等系统的数据。
            本地数据按照数据时间又可以划分为两部分,分别是历史数据与实时数据。
                历史数据是指系统在运行过程中遗存下来的数据,其数据量随系统运行时间的增加而增长
                实时数据是指最近一个单位时间周期(月、周、日、小时等)内产生的数据。

3. 数据预处理

        数据预处理的定义: 数据预处理是指对数据进行一系列操作的过程,包括数据合并、数据清洗、数据标准化和数据变换,以便将数据准备好用于后续的分析和建模工作。
        数据合并: 数据合并是将多张互相关联的表格或数据集合并为一张,以便在后续分析中使用。
        数据清洗: 数据清洗包括去除重复、缺失、异常或不一致的数据,确保数据质量符合分析和建模的要求。
        数据标准化: 数据标准化是为了消除不同特征之间的量纲差异,使得数据在相同的数值尺度上进行比较和分析。
        数据变换: 数据变换通过离散化、哑变量处理等技术,使得数据更符合后续分析与建模的需求,如改善数据分布的对称性或者满足特定模型的假设条件。
        数据预处理过程中的交叉操作: 在实际数据分析中,数据预处理的各个过程往往是互相交叉进行的,并没有固定的先后顺序,具体操作顺序可以根据数据的特点和分析的需求来灵活调整。

4. 分析与建模

        1.分析与建模的定义:分析与建模是通过多种分析方法和模型算法,从数据中发现有价值的信息并得出结论的过程。
        2.数据获取方式的依据:具体使用哪种数据获取方式取决于需求分析的结果,即根据分析目标来选择适合的方法。
        3.分析与建模方法的分类:根据不同的分析目标,分析与建模方法可以分为几大类,包括描述型数据分析、关联规则、序列规则、聚类模型以及分类预测模型和回归预测模型等。
        4.描述型数据分析方法:适合描述客户行为模式等情况,可以结合关联规则、序列规则和聚类模型等方法来分析数据。
        5.预测分析模型:预测分析模型分为分类预测模型和回归预测模型两大类,用于量化未来某事件发生概率或预测连续型数据,如欺诈与否、股票价格等。
        6.分类预测模型和回归预测模型的应用场景:分类预测模型适合处理目标特征为二元数据的情况,如欺诈与否、流失与否等;而回归预测模型则适合处理目标特征为连续型数据的情况,如股票价格预测等。

5. 模型评价与优化

        1. 模型评价的定义:模型评价是针对已建立的一个或多个模型,根据其类别使用不同指标来评估模型性能优劣的过程。
        2. 聚类模型评价指标:常用的聚类模型评价指标包括ARI评价法(兰德系数)、AMI评价法(互信息)、V-measure评分、FMI评价法和轮廓系数等,用于衡量聚类结果的质量和聚类算法的效果。
        3. 分类模型评价指标:常用的分类模型评价指标包括准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F1值(F1 Score)、ROC曲线和AUC(曲线下面积)等,用于评估分类模型的分类准确性和预测效果。
        4. 回归模型评价指标:常用的回归模型评价指标有平均绝对误差(MAE)、均方误差(MSE)、中值绝对误差(MedAE)和可解释方差值(Explained Variance Score)等,用于衡量回归模型预测结果的准确性和拟合程度。
        5. 模型优化的定义:模型优化是指在经过模型评价后发现模型在实际应用中表现不理想时,对模型进行重构与优化的过程。通常涉及调整模型参数、改进特征工程、优化算法选择等方法,以提高模型在生产环境中的表现。
        6. 模型优化与分析与建模过程的关系:大多数情况下,模型优化过程与分析与建模过程密切相关,因为优化过程往往建立在对模型评价结果的基础上,以进一步改进模型的预测能力和泛化能力。

6. 部署

        部署是指将数据分析结果与结论应用至实际生产系统的过程。
        根据需求的不同,部署阶段可以是一份包含了现状具体整改措施的数据分析报告,也可以是将模型部署在整个生产系统的解决方案。
        在多数项目中,数据分析师提供的是一份数据分析报告或一套解决方案,实际执行与部署的是需求方。

II科学计算库NumPy

2.1创建数组,数组运算,索引与切片

2.1.1.认识NumPy数组对象

        N维数组对象
        | 即ndarray(别名array)

2.1.2.创建NumPy数组

arange()函数

        | 通过arange()函数可以创建一个等差数组,它的功能类似于range(),只不过arange()函数返回的结果是数组,而不是列表。
        大家可能注意到,有些数组元素的后面会跟着一个小数点,而有些元素后面没有,比如1和1.,产生这种现象,主要是因为元素的数据类型不同所导致的。

2.1.3.查看数据类型

| NumPy的数据类型是由一个类型名和元素位长的数字组成。
ndarray.dtype
| ndarray.dtype可以创建一个表示数据类型的对象,如果希望获取数据类型的名称,则需要访问name属性进行获取。
e.gdata_one.dtype.name

        常用数据类型
            特征码
            | 每一个NumPy内置的数据类型都有一个特征码,它能唯一标识一种数据类型。


        astype()函数
        | ndarray对象的数据类型可以通过astype()方法进行转换。
            e.gdata = np.array([[1, 2, 3], [4, 5, 6]]) data.dtype# 数据类型转换为float64float_data = data.astype(np.float64)float_data.dtype

2.1.4.数组运算

矢量化运算
| 形状相同的数组
形状相等的数组之间的任何算术运算都会应用到元素级,即只用于位置相同的元素之间,所得的运算结果组成一个新的数组。
| 即每个位置逐个计算

        广播机制
        | 形状不同的数组
            当形状不相等的数组执行算术计算的时候,就会出现广播机制,该机制会对数组进行扩展,使数组的shape属性值一样,这样就可以进行矢量化运算了

            广播机制需要满足如下任意一个条件即可:                                          (1)两个数组的某一维度等长。(2)其中一个数组为一维数组。
                广播机制需要扩展维度小的数组
                | 使得它与维度最大的数组的shape值相同,以便使用元素级函数或者运算符进行运算。


        数组与标量运算
        | 标量
            标量运算会产生一个与数组具有相同行和列的新矩阵,其原始矩阵的每个元素都被相加、相减、相乘或者相除。

2.1.5.ndarray的索引和切片

2.1.5.1整数索引和切片的基本使用
一维数组
与Python列表的功能相差不大

            多维数组
                索引
                    在二维数组中,每个索引位置上的元素不再是一个标量了,而是一个一维数组。

                    如果想获取二维数组的单个元素,则需要通过形如“arr[x,y]”的索引来实现,其中x表示行号,y表示列号。

                切片
                    多维数组的切片是沿着行或列的方向选取元素的,我们可以传入一个切片,也可以传入多个切片,还可以将切片与整数索引混合使用。
        2.1.5.2花式(数组)索引的基本使用

如果用两个花式索引操作数组,则会将第1个作为行索引,第2个作为列索引,以二维数组索引的方式选取其对应位置的元素。
| 非坐标!
# 获取索引为(1,1)和(3,2)的元素demo_arr[[1, 3], [1, 2]]

        2.1.5.3布尔型索引的基本使用

布尔型索引指的是将一个布尔数组作为数组索引,返回的数据是布尔数组中True对应位置的值。

2.2利用数组进行数据处理

2.2.1NumPy通用函数

通用函数(ufunc)是一种针对ndarray中的数据执行元素级运算的函数,函数返回的是一个新的数组。
| 我们将ufunc中接收一个数组参数的函数称为一元通用函数,接受两个数组参数的则称为二元通用函数。

2.2.2利用NumPy数组进行数据处理

将条件逻辑转为数组运算
NumPy的where()函数是三元表达式x if condition else y的矢量化版本。
| 类bool

        数组统计运算

        数组排序
            sort()
            对任何一个轴上的元素进行排序,则需要将轴的编号作为sort()方法的参数传入
                e.garr.sort(0)


        检索数组元素
            all()函数
            | 用于判断整个数组中的元素的值是否全部满足条件,如果满足条件返回True,否则返回False。
                e.gnp.all(arr > 0)
                | # arr的所有元素是否都大于0

            any()函数
            | 用于判断整个数组中的元素至少有一个满足条件就返回True,否则就返回False。
                e.gnp.any(arr > 0)
                | # arr的所有元素是否有一个大于0


        唯一化及其他集合逻辑
            unique()函数
                针对一维数组,NumPy提供了unique()函数来找出数组中的唯一值,并返回排序后的结果。
                | 即消除相同的元素

            inld()函数
            | 数字1
                用于判断数组中的元素是否在另一个数组中存在,该函数返回的是一个布尔型的数组
                    e.garr = np.array([12, 11, 34, 23, 12, 8, 11])np.in1d(arr, [11, 12])


            其他函数

2.3转置和轴对称,通用函数

    数组的转置和轴对称
        转置
        | 数组的转置指的是将数组中的每个元素按照一定的规则进行位置变换。
        方法
        | T属性和transpose()方法
            简单的转置可以使用T属性,它其实就是进行轴对换而已。
            | 即x与y轴对换
            当使用transpose()方法对数组的shape进行调换时,需要以元组的形式传入shape的编号
                如果我们不输入任何参数,直接调用transpose()方法,则其执行的效果就是将数组进行转置,作用等价于transpose(2,1,0)。

            有时可能只需要转换其中的两个轴,这时可以使用swapaxes()方法,该方法需要接受一对轴编号,比如(1,0)。
            多学一招
                高维数据执行某些操作(如转置)时,需要指定维度编号,这个编号是从0开始的,然后依次递增1。其中,位于纵向的轴(y轴)的编号为0,位于横向的轴(x轴)的编号为1,以此类推。

2.4数据类型,线性代数模块,随机数模块

    线性代数模块
        numpy.linalg模块
            有一组标准的矩阵分解运算以及诸如逆和行列式之类的东西。
            | 例如,矩阵相乘,如果我们通过“*”对两个数组相乘的话,得到的是一个元素级的积,而不是一个矩阵点积。
            提供的其他函数


        dot()方法
        | 用于矩阵乘法
            | (看不懂就是线性代数没学好)

        矩阵点积的条件是矩阵A的列数等于矩阵B的行数

    随机数模块
        random模块
        | 与Python的random模块相比,NumPy的random模块功能更多,它增加了一些可以高效生成多种概率分布的样本值的函数。
            rand()函数隶属于numpy.random模块,它的作用是随机生成N维浮点数组
            seed()函数
                可以保证生成的随机数具有可预测性,也就是说产生的随机数相同。
                | 当调用seed()函数时,如果传递给seed参数的值相同,则每次生成的随机数都是一样的。当传递的参数值不同或者不传递参数时,则seed()函数的作用跟rand()函数相同,即多次生成随机数且每次生成的随机数都不同。
                    e.gnumpy.random.seed(seed=None)
                    | 上述函数中只有一个seed参数,用于指定随机数生成时所用算法开始的整数值。


            其他函数

Ⅲ数据分析工具Pandas

3.1 Pandas数据结构
3.1.1 Series

| 一维的数据结构。
class pandas.Series(data = None,index = None,dtype = None,name = None,copy = False,fastpath = False)
| data:表示传入的数据。 index:表示索引,唯一且与数据长度相等,默认会自动创建一个从0~N的整数索引。
ser_obj = pd.Series([1, 2, 3, 4, 5], index=[‘a’, ‘b’, ‘c’, ‘d’, ‘e’])
| # 创建Series类对象,并指定索引
year_data = {2001: 17.8, 2002: 20.1, 2003: 16.5}ser_obj2 = pd.Series(year_data)
| # 除了使用列表构建Series类对象外,还可以使用dict进行构建。
ser_obj.index # 获取ser_obj的索引
ser_obj.values # 获取ser_obj的数据
ser_obj[3] # 获取位置索引3对应的数据

        3.1.2 DataFrame

| 二维的、表格型(类似excel)的数据结构。
pandas.DataFrame(data = None,index = None,columns = None,dtype = None,copy = False )
| index:表示行标签。若不设置该参数,则默认会自动创建一个从0~N的整数索引。columns:列标签。
demo_arr = np.array([[‘a’, ‘b’, ‘c’], [‘d’, ‘e’, ‘f’]])
| # 创建数组
df_obj = pd.DataFrame(demo_arr)
| # 基于数组创建DataFrame对象
df_obj = pd.DataFrame(demo_arr, columns=[‘No1’, ‘No2’, ‘No3’])
| # 创建DataFrame对象,指定列索引
element = df_obj[‘No2’] # 通过列索引的方式获取一列数据
element = df_obj.No2 # 通过属性获取列数据
df_obj[‘No4’] = [‘g’, ‘h’] # 通过列索引赋值
del df_obj[‘No3’] # 删除No3一列数据

    3.2 索引操作及高级索引

3.2.1 索引对象
Pandas中的索引都是Index类对象,又称为索引对象,该对象是不可以进行修改的,以保障数据的安全。
Pandas还提供了很多Index的子类,常见的有如下几种:
(1)Int64Index:针对整数的特殊Index对象。
(2)MultiIndex:层次化索引,表示单个轴上的多层索引。
(3)DatetimeIndex:存储纳秒寄时间戳。

        3.2.2 重置索引

reindex()
DataFrame.reindex(labels = None,index = None,columns = None,axis = None,method = None,copy = True,level =
None,fill_value = nan,limit = None,tolerance = None )
| index:用作索引的新序列。 method:插值填充方式。 fill_value:引入缺失值时使用的替代值。 limit:前向或者后向填充时的最大填充量。
ser_obj2 = ser_obj.reindex([‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’], fill_value = 6) # 重新索引时指定填充的缺失值
| 如果不想填充为NaN,则可以使用fill_value参数来指定缺失值。
ser_obj3 = pd.Series([1, 3, 5, 7], index=[0, 2, 4, 6]) # 创建Series对象,并为其指定索引
ser_obj3.reindex(range(6), method = ‘ffill’) # 重新索引,前向填充值
ser_obj3.reindex(range(6), method = ‘bfill’)# 重新索引,后向填充值

        3.2.3 索引操作

ser_obj[2] # 使用索引位置获取数据
ser_obj[‘c’] # 使用索引名称获取数据
ser_obj[2: 4] # 使用位置索引进行切片
ser_obj[‘c’: ‘e’] # 使用索引名称进行切片
ser_obj[[0, 2, 4]] # 通过不连续位置索引获取数据集
ser_obj[[‘a’, ‘c’, ‘d’]] # 通过不连续索引名称获取数据集
ser_bool = ser_obj > 2 # 创建布尔型Series对象
ser_obj[ser_bool] # 获取结果为True的数据
行索引:index,列索引:columns
df_obj[: 2] # 使用切片获取第0~1行的数据
# 使用多个切片先通过行索引获取第0~2行的数据,再通过不连续列索引获取第b、d列的数据
| df_obj[: 3][[‘b’, ‘d’]]

            多学一招:操作索引
                loc:基于标签索引(索引名称),用于按标签选取数据。当执行切片操作时,既包含起始索引,也包含结束索引。
                    dataframe_obj.loc[:, ["c", "a"]]

                iloc:基于位置索引(整数索引),用于按位置选取数据。当执行切片操作时,只包含起始索引,不包含结束索引。
                    dataframe_obj.iloc[:, [2, 0]]
    3.3算术运算与数据对齐

obj_one.add(obj_two, fill_value = 0) # 执行加法运算,补充缺失值
| Pandas执行算术运算时,会按照索引进行对齐后进行相应的运算,没有对齐的位置会用NaN进行补齐。 如果希望不使用NAN填充缺失数据,则可以在调用add方法时提供fill_value参数的值,fill_value将会使用对象中存在的数据进行补充。

    3.4数据排序

3.4.1 按索引排序
ser_obj.sort_index() # 按索引进行升序排列
ser_obj.sort_index(ascending = False) # 按索引进行降序排列

        3.4.2 按值排序
            ser_obj.sort_values()   # 按值升序排列
            df_obj.sort_values(by = 2)  # 对列索引值为2的数据进行排序


    3.5统计计算与描述

3.5.1 常用的统计计算
df_obj.sum() # 计算每列元素的和
df_obj.max() # 获取每列的最大值
df_obj.min(axis=1) # 沿着横向轴,获取每行的最小值

        3.5.2 统计描述(descript)
            df_obj.describe()
            | percentiles:输出中包含的百分数,位于[0,1]之间。如果不设置该参数,则默认为[0.25,0.5,0.75],返回25%,50%,75%分位数。


    3.6 层次化索引

3.6.1 认识层次化索引
在一个轴方向上具有多层索引
在创建层次化索引对象时,嵌套函数中两个列表的长度必须是保持一致的,否则将会出现ValueError错误。
创建层次化索引的方法:
MultiIndex.from_tuples():将元组列表转换为MultiIndex。
| 其中元组的第一个元素作为外层索引,元组的第二个元素作为内层索引
MultiIndex.from_arrays():将数组列表转换为MultiIndex。
| 其中嵌套的第一个列表将作为外层索引,嵌套的第二个列表将作为内层索引
MultiIndex.from_product():从多个集合的笛卡尔乘积中创建一个MultiIndex。

        3.6.2 层次化索引的操作
            ser_obj['小说']     # 获取所有外层索引为“小说”的数据
            ser_obj[:,'自在独行']       # 获取内层索引对应的数据
            ser_obj.swaplevel()               # 交换外层索引与内层索引位置
            使用sort_index()方法排序时,会按外层索引,内层索引进行排序。

3.7读写数据操作
3.7.1 读写文本文件(.csv/.txt)

CSV
CSV文件是一种纯文本文件,可以使用任何文本编辑器进行编辑,它支持追加模式,节省内存开销。

            to_csv(path_or_buf=None,sep=',',na_rep='',float_format=None,columns=None,header=True,

index=True, index_label=None, mode=‘w‘, …)
| path_or_buf:文件路径。index:默认为True,若设为False,则将不会显示索引。sep:分隔符,默认用“,”隔开。
df.to_csv(r’E:/数据分析/itcast.csv’,index=False)

            read_csv(filepath_or_buffer,sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None, prefix=None,

…) # 转换成DataFrame对象
| sep:指定使用的分隔符,默认用“,”分隔。header:指定行数用来作为列名。names:用于结果的列名列表。如果文件不包含标题行,则应该将该参数设置为None。
read_csv()与read_table()函数的区别在于使用的分隔符不同,前者使用“,”作为分隔符,而后者使用“\t”作为分隔符。
如果希望读取Text文件,既可以用前面提到的read_csv()函数,也可以使用read_table()函数。

        3.7.2 读写Excel文件

to_excel(excel_writer,sheet_name=‘Sheet1’,na_rep=‘’,float_format=None,
columns=None, header=True, index=True, …)
| excel_writer:表示读取的文件路径。sheet_name:表示工作表的名称,默认为“Sheet1”。na_rep:表示缺失数据。index:表示是否写行索引,默认为True。
pandas.read_excel(io,sheet_name=0,header=0,names=None,index_col=None,
**kwds) # 转换成DataFrame对象
| io:表示路径对象。sheet_name:指定要读取的工作表,默认为0。header:用于解析DataFrame的列标签。names:要使用的列名称。
建议
excel_path =r’E:/数据分析/itcast.xlsx’ data = pd.read_excel(excel_path)

        3.7.3 读取HTML表格数据

html_data =
requests.get(‘http://kaoshi.edu.sina.com.cn/college/majorlist/’)html_table_data
= pd.read_html(html_data.content,encoding=‘utf-8’)

        3.7.4读写数据库

from sqlalchemy import create_engine # mysql账号为root 密码为123456
数据名:info # 数据表名称:person_infoengine =
create_engine(‘mysql+mysqlconnector://root:123456@127.0.0.1/info’)pd.read_sql(‘person_info’,engine)
from sqlalchemy import create_engine# mysql账号为root 密码为123456 数据名:info# 数据表名称:person_info# 创建数据库引擎# mysql+pymysql
表示使用Mysql数据库的pymysql驱动engine =
create_engine(‘mysql+mysqlconnector://root:123456@127.0.0.1/info’)sql
= 'select * from person_info where id >3;'pd.read_sql(sql,engine)
from sqlalchemy import create_enginefrom sqlalchemy.types import *df =
DataFrame({“班级”:[“一年级”,“二年级”,“三年级”,“四年级”],
“男生人数”:[25,23,27,30],
“女生人数”:[19,17,20,20]})# 创建数据库引擎# mysql+pymysql 表示使用Mysql数据库的pymysql驱动#
账号:root 密码:123456 数据库名:studnets_info# 数据表的名称:
studentsengine=create_engine(‘mysql+mysqlconnector://root:123456@127.0.0.1/students_info’)df.to_sql(‘students’,engine)

Ⅳ数据处理

    4.1数据清洗

4.1.1空值和缺失值的处理
pd.isnull(series_obj) # 检查是否为空值或缺失值
pd.notnull(series_obj) # 检查是否不为空值或缺失值
df_obj.dropna() # 删除数据集中的空值和缺失值
df_obj.fillna(‘66.0’) # 使用66替换缺失值
df_obj.fillna({‘A’: 4.0, ‘B’: 5.0}) # 指定列填充数据
df.fillna(method=‘ffill’) # 使用前向填充的方式替换空值或缺失值

        4.1.2重复值的处理

person_info.duplicated() # 从前向后查找和判断是否有重复值
person_info. drop_duplicates() # 删除重复值

        4.1.3异常值的处理

mean_value = ser1.mean() # 求平均值
std_value = ser1.std() # 求标准差
rule = (mean_value - 3 * std_value > ser1) | (ser1.mean() + 3 * ser1.std() < ser1) #3σ判定
| # 位于(μ-3σ,μ+3σ)区间的数据是正常的,不在这个区间的数据为异常的 # ser1中的数值小于μ-3σ或大于μ+3σ均为异常值 # 一旦发现有异常值,就标注为True,否则标注为False
index = np.arange(ser1.shape[0])[rule] # 返回异常值的位置索引
outrange = ser1.iloc[index] # 获取异常数据

        4.1.4更改数据类型

df.dtypes # 查看数据的类型
df[‘B’].astype(dtype=‘int’) # 强制转换为int类型
pd.to_numeric(ser_obj, errors=‘raise’) # 转换object类型为float类型

    4.2数据合并

4.2.1轴向堆叠数据
pd.concat([df1, df2], join=‘outer’, axis=1) # 横向堆叠合并df1和df2,采用外连接的方式
pd.concat([first, second], join=‘inner’, axis=0)

4.2.2主键合并数据
pd.merge(left, right, on=‘key’)
pd.merge(left, right, on=[‘key’, ‘B’])
pd.merge(left,right,how=‘outer’,left_index=True,right_index=True)

4.2.3索引合并数据
left.join(right, how=‘outer’)

    4.3数据重塑

4.3.1重塑层次化索引

            stack()
                可以将数据的列索引转换为行索引

            unstack()
            res = df.stack()  # 将df重塑为Series对象
            res.unstack()      # 将Series对象转换成df(DataFrame)
            df.stack(level=0)   # 旋转外层索引

        4.3.2轴向旋转
            df.pivot(index='', columns='', values='')

4.4转换数据
4.4.1 重命名轴索引

            df.rename(columns={'A':'a', 'B':'b', 'C':'c'}, inplace=True)    # 重命名列索引的名称,并且在原有数据上进行修改
            df.rename(str.lower, axis='columns')
            df.rename(index={1: 'a', 2: 'b'}, inplace=True)
        4.4.2 离散化连续数据
            cuts = pd.cut(arr1, arr2)    # 使用pandas的cut函数划分组
            pd.cut(arr1, arr2=arr2, right=False)
        4.4.3 哑变量处理类别型数据
            pd.get_dummies(df1, prefix=['col_前缀'])  # 哑变量处理

数据分析

V分组与聚合原理

5.1分组与聚合的原理

        分组是指使用特定的条件将原数据划分为多个组,聚合在这里指的是,对每个分组中的数据执行某些操作,最后将计算的结果进行整合。
        Pandas官方参考文档地址是http://pandas.pydata.org/pandas-docs/stable/groupby.html。
        过程大概分为三步:
            拆分
            | 将数据集按照一些标准拆分为若干个组。
            应用
            | 将某个函数或方法(内置和自定义均可)应用到每个分组
            合并
            | 将产生的新值整合到结果对象中。

5.2通过groupby()方法拆分数据

        df.groupby(by='Key')  # 按Key列进行分组
        groupby_obj = df.groupby(len)     # 使用内置函数len进行分组
        for i in group_obj:    print(i) # 遍历分组对象

5.3数据的聚合

        5.3.1使用内置统计方法聚合数据
            df.groupby('key1').mean() # 按key1进行分组,求每个分组的平均值

        5.3.2面向列的聚合方法(agg)
            data_group.agg(sum)# 求每个分组的列和
            data_group.agg(range_data_group)  # 使用自定义函数聚合分组数据
            | def range_data_group(arr):
            |     return arr.max()-arr.min()
            | 
            data_group.agg([("极差", range_data_group), ("和", sum)])  # 对一列数据用两种函数聚合
            data_group.agg({'a': 'sum', 'b': 'mean', 'c': range_data_group})  # 每列使用不同的函数聚合分组数据

5.4分组级运算

        5.4.1数据转型(transform)
            df.groupby(key).transform('mean')  # 以key为分组依据,对df对象进行分组
            | key = ['one','one','two',' two',' two']

        5.4.2数据应用(apply)
            dict([x for x in data_by_group])['a']# 打印分组数据
            data_by_group.apply(max)# 调用apply()方法聚合,求每个分组中的最大值

VI可视化分析

6.1数据可视化的概述

        6.1.1常见的图表类型
  • 直方图,又称作质量分布图,它是由一系列高度不等的纵向条纹或线段表示数据分布的情况,一般用横轴表示数据的类型,纵轴表示分布情况。
    | 直方图可以利用方块的高度来反映数据的差异,只适用于中小规模的数据集,不适用于大规模的数据集。
    折线图是用直线段将各数据点连接起来而组成的图形,以折线的方式显示数据的变化趋势。
    | 折线图可以显示随时间变化的连续数据,适用于显示在相等时间间隔下数据的趋势。
    条形图是用宽度相同的条形的高度或者长短来表示数据多少的图形,可以横置或纵置,纵置时也称为柱形图。
    饼图可以显示一个数据序列中各项的大小与各项总和的比例,每个数据序列具有唯一的颜色或图形,并且与图例中的颜色是相对应的。
    | 饼图可以很清晰地反映出各数据系列的百分比情况。
    在回归分析中,散点图是指数据点在直角坐标系平面上的分布图,通常用于比较跨类别的数据。散点图包含的数据点越多,比较的效果就会越好。
    | 散点图中每个坐标点的位置是由变量的值决定的,用于表示因变量随自变量而变化的大致趋势,以判断两种变量的相关性。
    箱形图又称为盒须图、盒式图或箱线图,是一种用作显示一组数据分散情况资料的统计图。
    | 箱形图提供了一种只用5个点对数据集做简单总结的方式。

             区别
             | 直方图:适于比较数据之间的多少。
             | ​折线图:反映一组数据的变化趋势。
             | ​条形图:显示各个项目之间的比较情况,和直方图有类似的作用。
             | ​散点图:显示若干数据系列中各数值之间的关系。
             | ​箱形图:识别异常值方面有一定的优越性
    

6.2Matplotlib绘制图表

    | Python2D绘图库

6.2.1通过figure()函数创建画布

如果不希望在默认的画布上绘制图形,则可以调用figure()函数构建一张新的空白画布。
matplotlib.pyplot.figure(num = None,figsize = None,dpi = None,facecolor = None,edgecolor = None, …,** kwargs)
| num – 表示图形的编号或名称。
| figsize – 用于设置画布的尺寸。
| ​facecolor – 用于设置画板的背景颜色。
| ​edgecolor – 用于显示边框颜色。

            调用figure()函数创建新的空白画布。
            | figure_obj = plt.figure()
        6.2.2通过subplot()函数创建单个子图

Figure对象允许划分为多个绘图区域,每个绘图区域都是一个Axes对象,它拥有属于自己的坐标系统,被称为子图。
要想在画布上创建一个子图,则可以通过subplot()函数实现。
subplot(nrows, ncols, index, **kwargs)
| nrows,ncols – 表示子区网格的行数、列数。
| ​ index – 表示矩阵区域的索引。

            subplot()函数会将整个绘图区域等分为“nrows (行)* ncols(列)”的矩阵区域,之后按照从左到右、从上到下的顺序对每个区域进行编号。其中,位于左上角的子区域编号为1,依次递增。
            如果nrows、ncols和index这三个参数的值都小于10,则可以把它们简写为一个实数。
        6.2.3通过subplots()函数创建多个子图

如果希望一次性创建一组子图,则可以通过subplots()函数进行实现。
subplots(nrows = 1,ncols = 1,sharex = False,sharey = False,squeeze = True,subplot_kw = None,gridspec_kw = None,** fig_kw)
| nrows,ncols – 表示子区网格的行数、列数。
| ​sharex,sharey – 表示控制x或y轴是否共享。

            subplots()函数会返回一个元组,元组的第一个元素为Figure对象(画布),第二个元素为Axes对象(子图,包含坐标轴和画的图)或Axes对象数组。如果创建的是单个子图,则返回的是一个Axes对象,否则返回的是一个Axes对象数组。
        6.2.4通过add_subplot()函数来添加和选中子图

还可以通过Figure类的add_subplot()方法添加和选中子图。
add_subplot(* args,** kwargs )
| 上述方法中,args参数表示一个三位数的实数或三个独立的实数,用于描述子图的位置。比如“a, b, c”,其中a和b表示将Figure对象分割成ab大小的区域,c表示当前选中的要操作的区域。

            每调用一次add_subplot()方法只会规划画布划分子图,且只会添加一个子图。当调用plot()函数绘制图形时,会画在最后一次指定子图的位置上。
        6.2.5添加各类图标

        6.2.6绘制常见图表

        6.2.7多学一招:图表正确显示中文

| 如果要设置的图表标题中含有中文字符,
| ​则会变成方格子而无法正确显示。
在python脚本中动态设置matplotlibrc,这样就可以避免由于更改配置文件而造成的麻烦。
# 设置显示中文字体
| from pylab import mpl
| ​mpl.rcParams[‘font.sans-serif] = [‘SimHei’]

            另外,由于字体更改以后,会导致坐标轴中的部分字符无法正常显示,这时需要更改axes.unicode_minus参数。
                # 设置正常显示符号
                | mpl.rcParams['axes.unicode_minus'] = False
        6.2.8多学一招:颜色、线型、标记的位置

| 在使用绘制图表的函数(比如plot等)画图时,可以设定线条的相关参数,包括颜色、线型和标记风格。
线条颜色使用color参数控制,它支持如下表所列举的颜色值。

            线型使用linestyle参数控制,它支持如下表所列举的线型值。

            标记风格使用marker参数控制,它支持如右表所列举的标记值。
        6.2.9多学一招:本地保存图形

| 在Jupyter Notebook中还可以在图形上右击另存为图片,或在PyCharm显示图形的窗口中,点击保存按钮进行保存。
要想保存当前生成的图表,可以调用savefig()函数进行保存。
| savefig(fname, dpi=None, facecolor=‘w’, edgecolor=‘w’, …)
fname参数是一个包含文件名路径的字符串,或者是一个类似于Python文件的对象。如果format 参数设为None且fname参数是一个字符串,则输出格式将根据文件名的扩展名推导出来。

6.3Seaborn绘制统计图形

6.3.1可视化数据的分布
Seaborn基于Matplotlib核心库进行了更高级的API封装,可以轻松地画出更漂亮的图形,而Seaborn的漂亮主要体现在配色更加舒服,以及图形元素的样式更加细腻。
| import seaborn as sns
另外,也可以在Jupyter Notebook中使用如下魔术命令绘图。
| %matplotlib inline
当处理一组数据时,通常先要做的就是了解变量是如何分布的。
| 对于单变量的数据来说,采用直方图或核密度曲线是个不错的选择。
| 对于双变量来说,可采用多面板图形展现,比如散点图、二维直方图、核密度估计图形等。
Seaborn中提供了一个distplot()函数,它默认绘制的是一个带有核密度估计曲线的直方图。
distplot(a, bins = None,hist = True,kde = True,rug = False, …)
| a – 表示要观察的数据。
| bins – 用于控制条形的数量。
| hist – 表示是否绘制(标注)直方图。
| kde** – 表示是否绘制高斯核密度估计曲线。
| ​rug – 表示是否在支持的轴方向上绘制rugplot。
如果希望使用Seaborn用Matplotlib的默认样式,则需要显式地调用set()或set_style()、set_context()和set_palette()中的一个或多个函数,以获取Seaborn或者Matplotlib默认的绘图样式。
e.g
| # 显式调用set()获取默认绘图sns.set()
| ​np.random.seed(0)
| ​arr = np.random.randn(100)
| ​# 绘制直方图
| ​ax = sns.distplot(arr, bins=10)

                核密度估计是在概率论中用来估计未知的密度函数,属于非参数检验方法之一,可以比较直观的看出数据样本本身的分布特征。
                | 直方图会因为条柱数量的不同导致图表的效果有着很大的差异,为了解决这个问题,可以绘制核密度估计曲线进行展现。
                    e.g
                    | array_random = np.random.randint(0, 100, 500)
                    | ​# 绘制核密度估计曲线
                    | ​sns.distplot(array_random, hist=False, rug=True)

                通过jointplot()函数可以创建一个多面板图形,以显示两个变量之间的关系及每个变量在单独坐标轴上的单变量分布。
                | seaborn.jointplot(x, y, data=None, kind='scatter', color=None, size=6, ratio=5, space=0.2, dropna=True,

xlim=None, ylim=None, …, **kwargs)
e.g
| dataframe_obj = pd.DataFrame({“x”:np.random.randn(500), “y”: np.random.randn(500)})#
绘制散布图sns.jointplot(x=“x”, y=“y”, data=dataframe_obj)

                调用jointplot()函数时只要传入kind=“hex”可以绘制二维直方图。
                | # 绘制二维直方图sns.jointplot(x="x", y="y", data=dataframe_obj, kind="hex")
                调用jointplot()函数时只要传入kind=“kde”可以绘制核密度估计图形。
                | `# 核密度估计
                | sns.jointplot(x="x", y="y", data=dataframe_obj, kind="kde")
                | `
                要想在数据集中绘制多个成对的双变量分布,则可以使用pairplot()函数实现,该函数会创建一个坐标轴矩阵,并且显示DataFrame对象中每对变量的关系。
        6.3.2用分类数据绘图

数据集中的数据类型有很多种,除了连续的特征变量之外,最常见的就是类目型的数据类型了。
Seaborn针对分类数据提供了专门的可视化函数,这些函数大致可以分为如下三种:
分类数据散点图:
通过stripplot()函数可以画一个散点图。
stripplot(x = None, y = None,hue = None,data = None,order = None,hue_order = None,jitter = False, …,**
kwargs)
| x,y,hue – 用于绘制长格式数据的输入。
| data – 用于绘制的数据集。如果x和y不存在,则它将作为宽格式,否则将作为长格式。order,hue_order – 用于绘制分类的级别。
| ​ jitter – 表示抖动的程度(仅沿类别轴)。
e.g
| # 加载内置的数据集tipstips = sns.load_dataset(“tips”)# 绘制散点图sns.stripplot(x=“day”, y=“total_bill”,
data=tips)
可以在调用stripplot()函数时传入jitter参数,以调整横坐标的位置。
| # 加载内置的数据集tipstips = sns.load_dataset(“tips”)# 绘制散点图sns.stripplot(x=“day”, y=“total_bill”,
data=tips, jitter=True)

                    还可以调用swarmplot() 函数绘制散点图,该函数的好处就是所有的数据点都不会重叠。
                        e.g
                        | # 加载内置的数据集tipstips = sns.load_dataset("tips")# 绘制散点图sns.swarmplot(x="day", y="total_bill",

data=tips)

                分类数据的分布图:

| 直观地反映出各个分类的数据分布
seaborn中用于绘制箱形图的函数为boxplot()。
seaborn.boxplot(x = None, y = None,hue = None,data = None,orient = None, palette = None,saturation = 0.75, …,
** kwargs)
| orient – 表示数据垂直或水平显示,取值为“v” | “h”。
| ​palette --用于设置不同级别色相的颜色变量。
| ​saturation – 用于设置数据显示的颜色饱和度。
e.g
| # 加载内置的数据集tipstips = sns.load_dataset(“tips”)# 绘制箱形图sns.boxplot(x=“day”, y=“total_bill”,
data=tips)

                    通过violinplot()函数可以绘制提琴图。
                        seaborn.violinplot(x = None,y = None,hue = None,data = None,order = None,hue_order = None,bw ='scott',cut =

2,scale =‘area’,scale_hue = True,gridsize = 100,width = 0.8,inner
=‘box’,split = False,dodge = True,orient = None,linewidth = None,color = None,palette = None,saturation = 0.75,ax = None,** kwargs)
e.g
| # 加载内置的数据集tipstips = sns.load_dataset(“tips”)# 绘制提琴图sns.violinplot(x=“day”, y=“total_bill”,
data=tips)

                分类数据的统计估算图:
                | 查看每个分类的集中趋势

默认情况下,barplot()函数会在整个数据集上使用均值进行估计。
| 若每个类别中有多个类别时(使用了hue参数),则条形图可以使用引导来计算估计的置信区间,并使用误差条来表示置信区间。
| ​置信区间,是指由样本统计量所构造的总体参数的估计区间。
e.g
| # 加载内置的数据集tipstips = sns.load_dataset(“tips”)# 绘制条形图sns.barplot(x=“day”, y=“total_bill”,
data=tips)

                    点图,可以调用pointplot()函数进行绘制。
                    | pointplot()函数会用高度估计值对数据进行描述,而不是显示完整的条形,它只会绘制点估计和置信区间。
                        e.g
                        | # 加载内置的数据集tipstips = sns.load_dataset("tips")# 绘制条形图sns.pointplot(x="day", y="total_bill",

data=tips)

6.4Bokeh交互式可视化库

6.4.1认识Bokeh库
Bokeh是针对浏览器使用的交互式可视化库,它旨在提供优雅、简洁的通用图形,帮助程序员快速地、轻松地创建交互图、数据应用程序等。
Bokeh库捆绑了多种语言,包括Python、R语言、lua和Julia,结合这些语言产生了JSON文档,此文档将作为BokehJS(JavaScript库)的输入,之后将数据展示到Web浏览器上面。
Bokeh提供了强大而灵活的功能,使其操作简单且高度定制化,它为用户提供了多个可视化界面,具体包含以下接口:
| 高级接口
| Charts
| 中级接口
| Plotting
| 底层接口
| Models

        Plotting是以构建视觉符号为核心的接口,可以结合各种视觉元素和工具创建可视化图形。

| 使用plotting创建图表的基本步骤如下:
| 第1步:导入Bokeh库中用到的一些方法或函数。
| 第2步:准备数据,可以Python列表,NumPy数组或Series对象。
| 第3步:选择输出方式:(1)使用output file()函数生成HTMML文档。(2)使用outputnotebook()函数用在JupyterNotebook上.
| 第4步:调用figure()创建一个具有典型默认选项的图形并且可以轻松地定制标题、工具和坐标轴标签
| 第5步:添加渲染器。
| 第6步:显示或保存图表,通过调用show()或save()函数将画好的图形保存到HTML文件,或选择性地将其显示在浏览器中,

有关Bokeh库的使用大同小异,都是基于上述的基本步骤完成的,大家可以参考官方文档(https://bokeh.pydata.org/en/latest/)绘制一些其它的图形。

VII时间序列数据分析

7.1时间序列基础

        7.1.1创建时间序列数据
            pd.to_datetime('20180828')   # 将datetime转换为Timestamp对象
            | #可传入多个datetime字符串
            date_index[0]      # 取出第一个时间戳
            date_ser = pd.Series([11, 22, 33], index=date_index)       # 创建时间序列类型的Series对象
            # 指定索引为多个datetime的列表
            | date_list = [datetime(2018, 1, 1), datetime(2018, 1, 15),             datetime(2018, 2, 20), datetime(2018, 4, 1),             datetime(2018, 5, 5), datetime(2018, 6, 1)]time_se = pd.Series(np.arange(6), index=date_list)

        7.1.2通过时间戳索引选取子集
            date_se = pd.Series(np.arange(6), index=date_index)   # 创建以DatetimeIndex 为索引的Series对象
            | # 指定索引为多个日期字符串的列表date_list = ['2015/05/30', '2017/02/01',             '2015.6.1', '2016.4.1',             '2017.6.1', '2018.1.23']#接受多格式时间表达
            | ​# 将日期字符串转换为DatetimeIndex date_index = pd.to_datetime(date_list)
            time_se[3]   # 根据位置索引获取数据
            date_se['20150530']    #通过数据索引
            date_se['2015']  # 获取2015年的数据
            sorted_se.truncate(before='2016-1-1')   # 扔掉2016-1-1之前的数据
            | after=之后

7.2固定频率的时间序列

        7.2.1创建固定频率的时间序列
            # 创建DatetimeIndex对象时,只传入开始日期与结束日期pd.date_range('2018/08/10', '2018/08/20'
            # 创建DatetimeIndex对象时,传入start/end与periods参数pd.date_range(start='2018/08/10', periods=5)
            | periods:时间段(长度)
            dates_index = 
            | pd.date_range('2018-01-01',         # 起始日期 
            |                            periods=5,            # 周期
            |                             freq='W-SUN')         # 频率(D,W,M,Y)
            e.g
                # 创建DatetimeIndex,并指定开始日期、产生日期个数、默认的频率,以及时区pd.date_range(start='2018/8/1 12:13:30', periods=5,               tz='Asia/Hong_Kong')
                #规范化时间戳pd.date_range(start='2018/8/1 12:13:30', periods=5,               normalize=True, tz='Asia/Hong_Kong')


        7.2.2时间序列的频率,偏移量
             DateOffset(months=4, days=5)
            | from pandas.tseries.offsets import *<DateOffset: days=5, months=4>
                Week(2) + Hour(10)
                | Timedelta('14 days 10:00:00')

            # 生成日期偏移量
            | date_offset  = Week(2) + Hour(10)
            | ​pd.date_range('2018/3/1', '2018/3/31', freq=date_offset)

        7.2.3时间序列数据的移动
            time_ser.shift(1)   # 向后移动一次
            | time_ser = pd.Series(略,略)
            | shift(-1)  #向前

7.3时间周期及计算

        7.3.1创建时期对象
            # 创建Period对象,表示从2018-01-01到2018-12-31之间的时间段pd.Period(2018)
            | 等同于p = pd.Period(2018,freq='A-DEC')   % freq ='A-DEC'表一年
            # 表示从2017-06-01到2017-06-30之间的整月时间                          period = pd.Period('2017/6')
            | period 可以直接+/-M
            | period 之间可以+/-

        7.3.2时期的频率转换
            period.asfreq('M', how='end')
            | freq #频率

7.4重采样

        7.4.1重采样方法(resample)
        | 重新
            time_ser.resample('W-MON', closed='left').mean()

        7.4.2降采样
        | 减少
            time_ser.resample('7D').ohlc()  # OHLC重采样
            time_ser.groupby(lambda x: x.week).mean()# 通过groupby技术实现降采样

        7.4.3升采样
        | 增加
            time_df.resample('D').asfreq()# 填NaN
            time_df.resample('D').ffill()# 取上一个数据填入

7.5数据统计——滑动窗口

    | 指的是根据指定的单位长度来框住时间序列,从而计算框内的统计指标。
    | 将某个时间点的数据用大约10个单位的数据平均值来代替
        每次窗口移动,一次只会移动一个单位的长度,并且窗口的长度始终为10个单位长度,直至移动到末端。
        | 通过滑动窗口统计的指标会更加平稳一些,数据上下浮动的范围会比较小。
        rolling(window, min_periods=None, center=False, win_type=None, on=None, axis=0, closed=None)
        | window      -- 表示窗口的大小。
        | ​min_periods -- 每个窗口最少包含的观测值数量。
        | ​center      -- 是否把窗口的标签设置为居中。
        | ​win_type    -- 表示窗口的类型。
        | ​closed      -- 用于定义区间的开闭。

    7.6时序模型——ARIMA
    | 时间序列预测模型
        介绍
            全称叫做差分整合移动平均自回归模型,又称作整合移动平均自回归模型,是一种用于时间序列预测的常见统计模型。
            组成
                AR,I,MA(p,d,q)模型
                | p--代表预测模型中采用的时序数据本身的滞后数,即自回归项数。
                | ​d--代表时序数据需要进行几阶差分化,才是稳定的,即差分的阶数。
                | ​q--代表预测模型中采用的预测误差的滞后数,即滑动平均项数。


        建立的基本步骤
            1.获取被观测的时间序列数据。
            2.根据时间序列数据进行绘图,观测是否为平稳时间序列。
            3.从平稳的时间序列中求得自相关系数ACF和偏自相关系数PACF,得到最佳的阶层p和阶数q。
            4.根据上述计算的d、q、p得到ARIMA模型,然后对模型进行检验。

        对于一个时间序列来说,如果它的均值没有系统的变化(无趋势),方差没有系统变化,并且严格消除了周期性的变化,就称为是平稳的。

Ⅷ文本数据分析

8.1文本数据分析工具

        8.1.1NLTK与 jieba概述
            NLTK全称为Natural Language Toolkit,它是一套基于Python的自然语言处理工具包,可以方便地完成自然语言处理的任务。
            | NLTK是一个免费的、开源的、社区驱动的项目,它为超过50个语料库和词汇资源(如WordNet)提供了易于使用的接口,以及一套用于分类、标记化、词干化、解析和语义推理的文本处理库。
                作用

                NLTK库中附带了许多语料库、玩具语法、训练模型等,完整的信息发布在http://nltk.org/nltk_data/网上。

            “Jieba”:最好的 Python 中文分词组件。
                特点
                | 支持三种分词模式
                | 支持繁体分词
                | 支持自定义词典
                | 
                分词模式
                | 试图将句子最精确地切开,适合文本分析。
                | 精确模式
                | 把句子中所有可以成词的词语都扫描出来速度非常快,但是不能解决歧义。
                | 全模式
                | 在精确模式的基础上对长词再次切分,提高召回率,适合用于搜索引擎分词。
                | 搜索引擎模式


        8.1.2安装nltk和下载语料库
            import nltk    nltk.download()    # 打开NLTK下载器
            | 检查包是否齐全

            from nltk.corpus import brown       # 导入brown语料库brown.words()                        # 查看brown库中所有的单词

        8.1.3jieba的安装
            pip install jieba

8.2文本预处理

        8.2.1预处理流程

        8.2.2分词
        | 将由连续字符组成的语句,
        | ​按照一定的规则划分成一个个独立词语的过程。
            英文
            | 以空格为分隔符
            中文
            | 没有形式上的分隔符
                分词算法
                | 按照一一定的策略将待分析的中文句子与一个“充分大的”机器词典中的词条进行匹配
                | 基于规则的分词方法
                | 它的基本思想是常用的词语是比较稳定的组合。
                | 基于统计的分词方法
                | 它的基本思想是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。
                | 基于理解的分词方法

            nltk
                 words = nltk.word_tokenize(sentence)    # 将句子切分为单词

            jieba
                要想使用jieba对中文句子分词,则可以通过jieba.cut() 函数进行划分
                | 该函数接收如下三个参数:
                | 需要分词的字符串。
                | cut all参数用来控制是否采用全模式。
                | HMM 参数用来控制是否使用 HMM 模型。
                | ​
                    e.g




        8.2.3词性标注
        | 为分词结果中的每个词标注一个正确的词性。
            nltk.pos_tag(words)   # 为列表中的每个单词标注词性
            词性是对词语分类的一种方式
                英文
                | 名词、形容词、动词、代词、数词、副词、介词连词、冠词和感叹词。
                中文
                | 名词、动词、形容词,数词、量词,代词、介词,副词、连词、感叹词、助词和拟声词。

            nltk约定

            nltk.pos_tag(words)    # 标注
            | 需要先确保已经下载了averaged_perceptron_tagger模块

        8.2.4词性归一化
        | 找词根
            # 导入nltk.stem模块的波特词干提取器
            | from nltk.stem.porter import PorterStemmer# 按照波特算法提取词干
            | ​porter_stem = PorterStemmer()porter_stem.stem('watched')
            # 导入nltk.stem模块的兰卡斯特词干提取器
            | from nltk.stem.lancaster import LancasterStemmer
            | ​lancaster_stem = LancasterStemmer()# 按照兰卡斯特算法提取词干lancaster_stem.stem('jumped')
            # 导入nltk.stem模块的Snowball词干提取器
            | from nltk.stem import SnowballStemmer
            | ​snowball_stem = SnowballStemmer('english')
            | ​snowball_stem.stem('listened')
            # 导入nltk.stem模块的WordNetLemmatizer词干还原
            | from nltk.stem import WordNetLemmatizer# 创建WordNetLemmatizer对象
            | ​wordnet_lem = WordNetLemmatizer()# 还原books单词的基本形式wordnet_lem.lemmatize('books')
                wordnet_lem.lemmatize('went', pos='v')   # 指定went的词性为动词


        8.2.5删除停用词
        | 排除已选好的停用词
            words = nltk.word_tokenize(sentence)   # 将英文语句按空格划分为多个单词
            stop_words = stopwords.words('english')    # 获取英文停用词列表
            e.g
                对于其它语言来说,可以参照https://www.ranks.nl/stopwords进行了解。

8.3文本情感分析

        8.3.1文本情感分析
        | 对设定好的语句进行赋分,并用特定方法处理后,形成一个训练模型
        | 
            大致思路:
            | 对文本进行分词操作,从中找出情感词、否定词以及程度副词。
            | 第1步
            | 判断每个情感词之前是否有否定词及程度副词,将它之前的否定词和程度副词划分为一组。
            | 第2步
            | 将所有组的得分加起来,得分大于0的归于正向,小于0的归于负向。
            | 第3步
            train(cls, labeled_featuresets , estimator = ELEProbDist)   #  主要用于根据训练集来训练模型
            |  labeled_featuresets -- 表示分类的特征集列表。
            | 
            | nltk.classify模块中的NaiveBayesClassifier类实现了朴素贝叶斯分类算法,该类中有一个类方法train(),主要用于根据训练集来训练模型。
            e.g

8.4文本相似度

        8.4.1文本相似度
        | 分别将两个文本的单词拆分,并记录词频,然后比较
            文本相似度的衡量计算方法
            | 基于关键字匹配的传统方法,比如N-gram相似度。
            | 关键字匹配
            | 将文本映射到向最空间,再利用余弦相似度等方法进行计算。
            | 映射向量
            | 比如卷积神经网络的ConvNet、用户点击数据的深度学习语义匹配模型DSSM等
            | 深度学习
            实现步骤:
            | 通过特征提取的模型或手动实现,找出这两篇文章的关键词。
            | 第1步
            | 认每篇文章中各取出若干个关键词,再把这些关键词合并成个集合,然后计算每篇文章中各个词对于这个集合中的关键词的词频。
            | 第2步
            | 生成两篇文章中各自的词频向量。
            | 第3步
            | 计算两个向量的余弦相似度,值越大则表示越相似。
            | 第4步
            e.g

8.5文本分类

        8.5.1文本分类
        | 将文本分为训练数据和测试数据
            e.g

            文本分类是指按照一定的分类体系或标准,用电脑对文本集进行自动分类标记,主要的目的是将文本或文档自动地归类为一种或多种预定义的类别
            实现步骤:
            | 包括数据集以及基本的预处理工作,用于将原始语料格式化为同一格式,便于后续进行统一处理。
            | 数据准备
            | 从文档中抽取出反映文档主题的特征
            | 特征抽取
            | 分类器模型会在个有标注数据集上进行训练。
            | 模型训练
            | 分类器的测试结果分析。
            | 结果评价

IXpyecharts

9.1概述

    matplotlib作为Python中著名的基础绘图库,它拥有着极其丰富的可视化功能,但其仍存在诸多不足,比如图表无法与用户交互、 API过于复杂等。为此,Python中引入了可视化神器——pyecharts库,使用pyecharts可以快速地生成效果惊艳的Echarts 图表。 
    与matplotlib相比, pyecharts库具有以下优势:
    | 简洁的API使开发者使用起来非常便捷,且支持链式调用。程序可在主流的Jupyter Notebook或JupyterLab工具上运行。程序可以轻松地集成至 Flask、Sanic、Django 等主流的Web框架中。灵活的配置项可以轻松搭配出精美的图表。详细的文档和示例可以帮助开发者快速地上手。400多个地图文件、原生百度地图为地理数据可视化提供强有力的支撑。
    Echarts的底层基于ZRender(二维绘图引擎,支持Canvas、SVG、VML等多种渲染方法)创建了坐标系、图例、提示框等基础组件,并基于这些组件创建了丰富的图表,包括常见的折线图、柱形图、散点图、饼图等;用于地理数据可视化的统计地图、热力图等;用于关系数据可视化的树状图、旭日图;用于多维数据可视化的平行坐标;用于BI 的漏斗图、仪表盘,还有任意混搭展现的组合图表。
    Echarts
    | 标题组件:包括主标题和副标题,位于图表的左上角。 
    | ​图例组件:位于图表的顶部中心位置,用户通过单击可显示或隐藏图例项对应的图形。
    | ​ 提示框组件:用于显示鼠标悬浮在图形上方的提示内容。 数据区域缩放组件:用于供用户选择关注细节的数据信息、概览图形数据的整体或去除离群点的影响 。
    | ​视觉映射组件:标识某一数值范围内数值及颜色对应关系的控件,可细分为分段型视觉映射组件和连续型视觉映射组件。 
    | 时间线组件……

9.2pyecharts基础知识

    9.2.1快速绘制图表
        e.g
        | # 创建 Bar 类的对象 , 并指定画布的大小bar = Bar(init_opts=opts.InitOpts(                 width='600px', height='300px' ))# 添加 x 轴和 y 轴的数据bar.add_xaxis(["衬衫", "羊毛衫", "雪纺衫",                         "裤子", "高跟鞋", "袜子"])bar.add_yaxis("商家A", [5, 20, 36, 10, 75, 90])# 设置标题、y 轴标签bar.set_global_opts(title_opts=opts.TitleOpts(title="柱形图示例"),yaxis_opts=opts.AxisOpts(name="销售额(万元)", name_location="center", name_gap=30))bar.render_notebook()
        链式调用是指简化同一对象多次访问属性或调用方法的编码方式,以避免多次重复使用同一个对象变量,使代码变得简洁、易懂。

    9.2.2认识图表类
        
        图表类均继承自Base基类,它们都可以使用与类同名的构造方法创建相应的图表实例。例如,Bar类的构造方法的语法格式如下:
        | Bar(init_opts=opts.InitOpts())
            以上方法的init_opts参数表示初始化配置项,该参数需要接收一个InitOpts类的对象,通过构建的InitOpts类对象为图表指定一些通用的属性,比如画布大小等。
            | bar = Bar(init_opts=opts.InitOpts(width='600px', height='300px'))


    9.2.3认识配置项
        全局配置项
            全局配置项是一些针对图表通用属性的配置项,包括初始化属性、标题组件、图例组件、工具箱组件、视觉映射组件、提示框组件、数据区域缩放组件,其中每个配置项都对应一个类。
                

            若pyecharts需要为图表设置全局配置项(InitOpts除外),则需要将全局配置项传入set_global_options()方法。set_global_options()方法的语法格式如下: 
                set_global_opts(self, title_opts=opts.TitleOpts(), legend_opts=opts.LegendOpts(),…, axispointer_opts=None)
                | title_opts:表示标题组件的配置项。
                | legend_opts:表示图例组件的配置项。
                | tooltip_opts:表示提示框组件的配置项。
                | toolbox_opts:表示工具箱组件的配置项。
                | brush_opts:表示区域选择组件的配置项。
                | xaxis_opts,yaxis_opts:表示x、y轴的配置项。
                | ​visualmap_opts:表示视觉映射组件的配置项。
                | ​datazoom_opts:表示数据区域缩放组件的配置项。
                | ​graphic_opts:表示原生图形元素组件的配置项。
                | ​axispointer_opts:表示坐标轴指示器组件的配置项。


        系列配置项
            系列配置项是一些针对图表特定元素属性的配置项,包括图元样式、文本样式、标签、线条样式、标记样式、填充样式等,其中每个配置项都对应一个类。 
                

            前面介绍的系列配置项类都可以通过与之同名的构造方法创建实例。创建一个标签配置项:
            label_opts = opts.LabelOpts(is_show=True, position='right', color='gray', font_size=14, rotate=10)
            | 以上示例中,LabelOpts()方法的参数is_show设为True,表示显示标签;
            | ​参数position设为'right',表示标注于图形右方;
            | ​参数color设为'gray',表示标签文本的颜色为灰色;
            | ​参数font_size设为14,说明标签文本的字体大小为14号;
            | ​参数rotate设为10,说明标签逆时针旋转10度。
            若pyecharts需要为图表设置系列配置项,则需要将系列配置项传入add()或add_xx()方法(直角坐标系图表一般使用add_yaxis()方法)中。
            | bar.add_yaxis(“商家A”, [5, 20, 36, 10, 75, 90],                             label_opts=opts.LabelOpts(is_show=False))
            pyecharts可以通过构造方法或字典两种方式创建配置项,两者是等价的。


    9.2.4渲染图表
        render()
            render()方法用于将图表渲染到HTML文件,默认为位于程序根目录的render.html文件。
            render(self, path="render.html", template_name="simple_chart.html", env=None, **kwargs)
            | path:表示生成文件的路径,默认为“render.html”。
            | ​template_name:表示模板的路径。
            | ​render()方法会返回HTML文件的路径字符串。

        render_notebook()
            render_notebook()方法用于将图表渲染到Jupyter Notebook工具中,它无需接收任何参数。
            bar.render_notebook()

9.3绘图

    pyecharts绘制各种图表的过程大致相同
    | 可以分为以下几步:
    | ​(1)创建与图表对应类的对象。(2)添加图表数据。(3)添加图表系列配置项。(4)添加图表全局配置项。(5)渲染图表。
    9.3.1绘制折线图
        pyecharts的Line类表示折线图,该类中提供了一个add_yaxis()方法,使用add_yaxis()方法可以为折线图添加数据和配置项。 
        add_yaxis(self, series_name, y_axis, is_selected=True, is_connect_nones=False, xaxis_index=None, …itemstyle_opts= None)
        | series_name:表示系列的名称,显示于提示框和图例中。
        | ​y_axis:表示系列数据。
        | ​color:表示系列的注释文本的颜色。
        | ​is_symbol_show:表示是否显示标记及注释文本,默认为True。

    9.3.2绘制饼图和圆环图
        pyecharts的Pie类表示饼图,该类中提供了一个add()方法,使用add()方法可以为饼图添加数据和配置项。 
        add(self, series_name, data_pair, color=None, radius=None, center=None, rosetype=None, is_clockwise=True,…, itemstyle_opts=None)
        | series_name:表示系列的名称,显示于提示框和图例中。
        | ​data_pair:表示系列数据帧。
        | ​radius:表示饼图的半径,可以接收一个包含两个元素的数组,其中数组的第一项为内半径,第二项为外半径。
        | ​center:表示饼图的中心坐标。
        | ​is_clockwise:表示饼图的扇区是否按顺时针排布。

    9.3.3绘制散点图
        pyecharts的Scatter类表示散点图,EffectScatter类表示带有涟漪特效的散点图,这两个类中均提供了一个add_yaxis()方法,使用add_yaxis()方法可以为散点图添加数据和配置项。 
        add_yaxis(self, series_name, y_axis, is_selected=True, xaxis_index=None, yaxis_index=None, color=None,…, itemstyle_opts=None)
        | series_name:表示系列的名称,显示于提示框和图例中。
        | ​y_axis:表示系列数据。is_selected:表示是否选中图例。
        | ​symbol:表示标记的图形。symbol_size:表示标记的大小。

    9.3.4绘制3D柱形图
        pyecharts的Bar3D类表示3D柱形图,该类中提供了一个add()方法,使用add()方法可以为3D柱形图添加数据和配置项。
        add(self, series_name, data, shading=None, itemstyle_opts=None,    ,…,grid3d_opts=opts.Grid3DOpts())
        | series_name:表示系列的名称。
        | ​data:表示数据。
        | ​shading:表示阴影。
        | ​xaxis3d_opts:表示x轴的配置项。
        | ​yaxis3d_opts:表示y轴的配置项。
        | ​zaxis3d_opts:表示z轴的配置项。

    9.3.5绘制统计地图
        pyecharts的Map类表示统计地图,该类中提供了一个add()方法,使用add()方法可以为统计地图添加数据和配置项。 
        add(self, series_name, data_pair, maptype="china", is_selected=True, is_roam=True, center=None, …, emphasis_itemstyle_opts=None)
        | series_name:表示系列的名称。
        | ​data_pair:表示数据项,可以为诸如(坐标点名称, 坐标点值)形式的值。
        | ​maptype:表示地图的类型。
        | ​zoom:表示当前视角的缩放比例,默认值为1。
        | ​is_map_symbol_show:表示是否显示标记图形。

    9.3.6绘制漏斗图
        pyecharts的Funnel类表示漏斗图,该类中提供了一个add()方法,使用add()方法可以为漏斗图添加数据和配置项。 
        add(self, series_name, data_pair, is_selected=True, color=None, sort_="descending", gap=0, , itemstyle_opts=None)
        | series_name:表示系列的名称。
        | ​data_pair:表示系列数据项。
        | ​is_selected:表示是否选中图例。
        | ​sort_:表示数据排序,可以取值为'ascending'、'descending'或'none'。
        | ​gap:表示数据图形的间距,默认为0。

    9.3.7绘制桑基图
        pyecharts的Saneky类表示桑基图,该类中提供了一个add()方法,使用add()方法可以为桑基图添加数据和配置项。 
        add(self, series_name, nodes, links, is_selected=True, node_width=20, node_gap=8, …, tooltip_opts=None)
        | series_name:表示系列的名称。
        | ​nodes:表示分支的序列。
        | ​links:表示链接的序列。
        | ​node_width:表示分支的宽度。
        | ​node_gap:表示分支的间隔。

9.4制作组合图表

    除了前面介绍的单图表,pyecharts也支持绘制组合图表,即同一画布显示的多个图表。多个图表按照不同的组合方式,可以分为并行多图、顺序多图、选项卡多图和时间轮播多图。 
    9.4.1并行多图
        pyecharts.charts的Grid类表示并行排列的组合图表,它可以采用左右布局或上下布局的方式显示多个图表。Grid类中包含一个add()方法,使用add()方法可以为组合图表添加图表或配置项。
        add(self, chart, grid_opts, grid_index=0, is_control_axis_index=False)
        | chart:表示图表。grid_opts:表示直角坐标系配置项。grid_index:表示直角坐标系网格索引,默认为0。is_control_axis_index:表示是否由自己控制坐标轴索引,默认为False。

    9.4.2顺序多图
        pyecharts.charts的Page类表示顺序显示的组合图表,它可以在同一网页中按顺序渲染多个图表。Page 类的构造方法的语法格式如下所示: 
        Page(page_title="Awesome-pyecharts", js_host= "", interval=1, layout=PageLayoutOpts())
        | page_title:表示HTML网页的标题。js_host:表示远程的主机地址,默认为"https://assets.pyecharts.org/assets/"。interval:表示每个图例之间的间隔,默认为1。layout:表示布局配置项。
        Grid类提供了一个add()方法,使用add()方法可以为组合图表添加多个图表实例。
        add(*charts)
        | charts: 任意图表实例

    9.4.3选项卡多图
        pyecharts.charts的Tab类表示以选项卡形式显示的组合图表,它可以点击不同的选项卡来切换显示多个图表。Tab类的构造方法的语法格式如下所示:
        Tab(page_title="Awesome-pyecharts", js_host="")
        | 以上方法的参数与Page()方法的参数相同,此处不再赘述。
        Tab类提供了一个add()方法,使用add()方法可以为组合图表添加图表。add()方法的语法格式如下所示:
        add(self, chart, tab_name)
        | 以上方法的参数chart表示任意图表,tab_name表示选项卡标签的名称。

    9.4.4时间线轮播多图
    | 它可以通过点击时间线的时间节点来切换显示多个图表。
        add_schema()方法用于为图表添加指定样式的时间线。
        add_schema(self, axis_type="category", orient="horizontal", symbol=None, symbol_size=None, …, itemstyle_opts=None)
        | axis_type:表示坐标轴的类型,可以取值为'value'(数值轴)、'category'(类目轴)、'time'(时间轴)、'log'(对数轴)。orient:表示时间线的类型,可以取值为'horizontal'(水平)和'vertical'(垂直)。play_interval:表示播放的速度,单位为ms。
        | is_auto_play:表示是否自动播放,默认为False。is_loop_play:表示是否循环播放,默认为True。is_rewind_play:表示是否反向播放,默认为False。is_timeline_show:表示是否显示时间线组件。width:表示时间线区域的宽度。height:表示时间线区域的高度。
        add ()方法用于添加图表和时间点。
        add(self, chart, time_point)
        | chart:表示图表。time_point:表示时间点。

pyecharts.faker包

        pyecharts.faker是一个pyecharts官方提供的测试数据包,它包含一个_Faker类的对象Faker,通过Faker对象访问属性来获取一些测试数据。
            

        除此之外,Faker对象还包含两个比较常用的方法:choose()和values(),其中choose()是一个实例方法,用于从前面表格的前7组测试数据中随机获取一组测试数据;values()是一个静态方法,用于生成一个包含7个随机整数n(20<=n<=150)的列表。


9.5定制图表主题
    pyecharts 内置了十多种不同风格的图表主题,包括LIGHT、DARK、CHALK等,并将这些图表主题封装为全局变量ThemeType引用类的属性中。
        

    前表中列举的属性可以传入InitOpts()方法的theme参数,之后在初始化图表类时将InitOpts类对象传给init_opts参数,如此便修改了图表默认的主题风格。