Python数据分析可视化之Pandas的使用

一、项目介绍

  • 数据获取与存储:能够使用Python财经数据接口包tushare下载股票交易数据,并将数据保存到CSV文件或MySQL数据库中。
  • 数据处理:能够用Pandas从CSV文件、Excel文件以及MySQL数据库中读取数据。能够使用Pandas对数据进行简单处理和深度处理,如数据的增删改查、数据去重、缺失处理、数据转换以及数据标准化等。
  • 数据统计分析:能够通过Pandas的groupby、agg和transform方法实现数据的聚合,并完成数据的统计分析工作。

二、数据获取与存储

2.1、数据获取

tushare是一个免费、易用的Python财经数据接口包,能够快速、便捷的获取股票、基金、黄金等金融数据

  • 下载并安装tushare

 pip install tushare

  • 注册用户,进入个人主页,在“接口TOKEN”选项卡中将token值复制下来。

  • 新建一个Python项目,获取股票代码:

 import tushare as ts
 # 设置token值
 ts.set_token("2022fef40058599bb7458609a6ad277edda3193a92b80513f27bb73a")
 # 获取格力电器股票交易数据
 df = ts.pro_bar(ts_code='000651.SZ',  # 股票代码
                  start_date='20180101',  # 起始时间
                  end_date='20200930')  # 结束时间
 # 保存为Excel文件
 df.to_excel("格力电器.xlsx")

to_excel()函数的常用参数

参数描述
excel_wirter用于指定文件路径或者ExcelWirter
sheetname用于设置sheet名称,默认为Sheet1
na_rep用于设置在遇到NaN值的代替字符,默认为空字符
columns用于设置需要保存的列,默认为None
header用于设置是否保留列名,默认为True
index用于设置是否保留索引,默认为True
encoding用于指定文件编码格式

2.2、数据存储

2.2.1、存储到CSV文件中

to_csv()函数用于将数据存储到文本文件中,其用法与to_excel() 函数类似

to_csv()函数的常用参数

参数描述
path_or_buf用于指定文件路径
sep用于设置分隔符,默认为逗号
na_rep用于设置遇到缺失值的替代字符,默认为空字符
columns用于设置需要保存的列,默认为None(全选)
header用于设置是否保留列名,默认为True
index用于设置是否保留索引,默认为True
encoding用于设置文件编码格式,默认为UTF-8格式
 df.to_csv("格力电器.csv",       # 文件名
           sep=",",             # 间隔符
           na_rep="99999",       # 缺失值使用99999代替
           header=True,          # 保留列名
           index=False)      # 不保留索引

2.2.2、存储到数据库中

  1. 搭建MySQL数据库服务器

  2. python连接MySQL数据库服务器。

 pip install pymysql

# 连接数据库
 ​
 #  导入sqlalchemy库
 from sqlalchemy import create_engine
 # 创建一个MySQL连接器对象engine
 # 用户名为root,密码为1234
 # 地址为127.0.0.1(本地),端口为3306
 # 数据库名称为stock,编码格式为UTF-8
 engine = create_engine("mysql+pymysql://root:1234@127.0.0.1:3306/stock?charset=utf8")
  1. 将股票数据存储于MySQL数据库中。 使用to_sql()函数将数据存储到名为stock的MySQL数据库服务器中。

df.to_sql("geli",       # 表名称
           con=engine,   # 数据库连接器对象
           index=False,  # 不保留索引
           if_exists="replace")  # 如果表已存在,则先删除再重新创建表

to_sql()函数的常用参数:

参数描述
name用于设置表名称。string型,无默认值
con用于设置数据库连接对象,无默认值
if_exits用于设置表名已存在的情况,可设为"fail","replace","append"。其中,'fail'表示引发ValueError错误,不执行写入操作,为默认选项;'replace'表示删除原有表,再重新创建新表;‘append’表示将新值追加到现有表中
index用于设置是否将索引写入到表中。值为boolean型,默认为Rrue
index_label用于设置索引的名称,如果该参数为None且index为True,则使用索引名。如果为多重索引,则应该使用sequence形式。默认为None
chunksize用于设置一次要写入的行数。默认将所有行一次写入。值为int,可选
dtype用于设置写入的数据类型。值为dict型(列名为key,数据格式为value)或标量(应用于所有列)。默认为None

三、数据读取

3.1、读取CSV文件中的数据

 import pandas as pd
 # 读取CSV文件
 data = pd.read_csv("格力电器.csv") #CSV文件路径
 print(data)

read_csv()函数的常用参数:

参数名称描述
filepath_or_buffer用于设置文件路径
sep用于设置分割符。默认为逗号“,”,read_table默认为制表符"[Tab]"
header用于设置第几行作为列名,默认为0(第一行)。如果文件没有标题行,则设置为None
names用于设置自定义的列名,默认为None
index_col用于设置某一列作为DataFrame的行名,如果没有这样的列,则设置为None
usercols读取按列划分的子集,有以下两种取值。None:读取所有列,默认值;列表:如[0,2,4]表示列的索引,["ts_code","high"]表示列名
dtype用于设置读取的数据类型(列名为key,数据格式为values)。默认为None
skiprows用于设置开头要跳过的行数,默认为None(不跳过任何行)
nrows用于设置要读取数据的条数,默认为None(全部读取)
encoding编码格式
# 例子:自定义DataFrame的列名为“A","B","C","D"...
 data = pd.read_csv("格力电器.csv",
                    skiprows=1,      # 忽略第一列的列名
                    names=[chr(i) for i in range(65,65+11)] ) # 自定义列名
 print(data)
 # 例子:跳过前5条数据
 data = pd.read_csv("格力电器.csv",
                    header=None,     #设置成无标题格式
                    skiprows=5)      # 忽略前5条数据
 print(data)
 # 读取前10条数据中的trade_date、open、high和low这几列数据
 data = pd.read_csv("格力电器.csv",
                    nrows=10,        #获取10条数据
                    usecols=['trade_date','open','high','low']) # 按名称获取相应列
 print(data)

3.2、读取Excel文件中的数据

import pandas as pd
 data =pd.read_excel("格力电器.xlsx",        # Excel文件路径
                     sheet_name='Sheet1',      # Excel中sheet名称
                     index_col=0)              # 将第一列作为列名
 print(data)

read_excel()函数的常用参数

参数名称描述
io文件路径
sheet_nameExcel内sheet的名称或位置,默认为0。接收string、int或list型
header设置第几列作为列名,默认为0(第一行),如果文件没有标题行,则设置为None
names设置自定义的列名,默认为None
index_col设置某一列作为DataFrame的行名,如果没有这样的列,默认为None
usecol读取按列划分的子集,划分范围的方法有以下几种:None:读取所有列,默认;字符串:如"A:E"表示读取列A到列E子集所有的数据。列表:如[0,2,4]表示列的索引,["ts_code","high"]表示列名
dtype代表读取的数据类型(列名为key,数据格式为values)。默认为None
skiprows开头要跳过的行数,默认为None
nrows要读取数据的条数,默认为None

3.3、获取MySQL数据库中的数据

Pandas提供了3个从数据库中获取数据的函数。

  • read_sql_table(),详细用法如下:

pandas.read_sql_table(table_name,con,scheme='None',index_col='None',coerce_float='True',parse_dates='None',columns='None',chunksize: None = 'None')
  • read_sql_query(),详细用法如下:

     pandas.read_sql_query(sql,con,index_col='None',coerce_float='True',params='None',parse_dates='None',chunksize: None = 'None')
  • read_sql(),详细用法如下:

    pandas.read_sql(sql,con,index_col='None',coerce_float='True',params='None',parse_dates='None',columns='None',chunksize: None = 'None')

3个数据库数据读取函数的常用参数:

参数名称描述
sql或table_namestring型。读取数据表的表名或SQL语句
con数据库连接对象
index_col设置某一列作为DateFrame的行名,如果没有这样的列,则设置为None
coerce_floatboolen型。将数据库中的decimal类型的数据转换为Pandas的float64类型数据,默认为True
parse_dateslist或dict型。解析为日期的列名
columnslist型。要从SQL表中读取列名的列表(仅在读取表时使用)。默认为None
 # 各使用方法例子:
 ​
 import pandas as pd
 from sqlalchemy import create_engine
 ​
 engine = create_engine("mysql+pymysql://root:1234@127.0.0.1:3306/stock?charset=utf8")
 ​
 # 读取数据库的表geli中的所有数据
 data1 = pd.read_sql_table("geli",con=engine)
 # 使用SQL语句获取表中的数据
 data2 = pd.read_sql_query("select * from geli",con=engine)
 # 查询数据库stock中的所有表名称
 data3 = pd.read_sql_query("show tables",con=engine)
 # 即可读取表也可通过SQL实现查询功能
 data4 = pd.read_sql("geli",con=engine)
 data5 = pd.read_sql("select * from geli",con=engine)

四、数据简单处理

Pandas也有属于自己的数组对象:SeriesDataFrame

  • series带有标签的一维数组对象,类似于DataFrame的一列

  • DataFrame带有行名和列名二维数组对象,类似于Excel表格。NumPy的ndarray数组只能存储同类型数据,而DataFrame支持不同数据类型的数据

4.1、常用属性

属性说明属性说明
values获取元素值size获取元素个数
index获取行索引shape获取数组维度(行列数)
columns获取列索引dtype获取数据类型
ndim获取维度数T转置
# 例子:
 import pandas as pd
 data = pd.read_csv("格力电器.csv")
 ​
 print("1.获取所有值:\n",data.values)
 print("2.获取行索引:\n",data.index)
 print("3.获取列索引:\n",data.columns)
 print("4.获取元素个数:\n",data.size)
 print("5.获取数组维度:\n",data.shape)
 print("6.获取数据类型:\n",data.dtypes)
 print("7.获取数组维度:\n",data.ndim)
 data1 = data.T
 print("8.数据转置后的维度:\n",data.shape)

4.2、查找数据

DataFrame既有普通数组的特点,又有自己独有的特征,它拥有行名,列名,因此非常方便于查找DataFrame中不同范围的数据。

4.2.1、使用字典Key查找数据

 a = [[1,2,3],
      [4,5,6]]
 a[1][1] # 访问第2行第2列的数 5
 # 例子
 import pandas as pd
 data = pd.read_csv("格力电器.csv")
 ​
 # 获取交易日期(trade_date)列的数据
 print(data["trade_date"])   # 返回一个Series类型的数组对象
 ​
 # 获取交易日期(trade_date)和收盘价(close)这两列数据。
 print(data[["trade_date","close"]])
 ​
 # 获取交易日期(trade_date)和收盘价(close)这两列的前5条数据
 print(data[["trade_date","close"]][:5])
 ​
 # 获取前5条交易数据
 print(data[:5])

注意:使用字典key的形式访问DataFrame数据的一般形式如下

 a[列名][行名/行索引值]

即先确定行,再确定列。另外,确定列的范围时,不能通过“:”来划定(访问所有列除外)。比如要访问前5行前5列的数据:

 print(data[:"close"][:5]) # 这种方式是错误的
 print(data[["trade_date","open","high","low","close"]][:5])  # 正确方法

4.2.2、使用切片查找数据

DataFrame提供了两种切片函数loc()iloc(),使得DataFrame不仅可以截取任意行和列范围的数据,而且还可以自由选择使用行/列名或者索引值查找。

loc()和iloc()的不同之处在与loc()是针对DataFrame行/列名的切片函数,如果传入的不是行/列名,操作将无法执行。iloc()接收的必须是行索引值和列索引值(与ndarry的切片函数一样)

 # 获取交易日期(trade_date)列的数据
 data = pd.read_csv("格力电器.csv")
 data.loc[:,"trade_date"]    # 方法1
 data.iloc[:,1]              # 方法2
  • 使用loc()函数截取数据时,要使用行名和列名,而iloc()则要使用行和列的索引值

# 获取交易日期(trade_date)和收盘价(close)这两列数据
 data.loc[:,["trade_date","close"]]  # 方法1
 data.iloc[:,[1,5]]                  # 方法2
  • 要截取的行或列不是一个连续的范围,可以列举出这些行或列对应的名称或者索引

# 获取交易日期(trade_date)和收盘价(close)这两列前5条数据
 print(data.loc[:4,["trade_date","close"]])  # 方法1 4表示行名
 print(data.iloc[:5,[1,5]])                  # 方法2
  • 获取前5行数据时,行范围:“:4”,4表示行名,并非行的索引值。

# 获取前5条交易数据
 print(data.loc[:4])
 print(data.iloc[:5])

4.2.3、使用条件查找

DataFrame还支持使用条件表达式来查找数据。

 # 查找收盘价小于50的数据
 print(data[data["close"]<50.0])
 ​
 # 查找收盘价小于50时的交易日期(trade_date)和涨跌幅(pac_chg)
 print(data.loc[data["close"]<50.0,["trade_date","pct_chg"]])
 ​
 # 查找收盘价小于50并且开盘价大于50时的所有数据
 print(data[(data["close"]<50.0) & (data["open"]>50.0)])
 ​
 # 查找收盘价小于50并且开盘价大于50时的交易日期
 print(data.loc[(data["close"]<50.0) & (data["open"]>50.0),"trade_date"])

4.3、组装数据

4.3.1、拼接数据

Pandas的拼接函数concat()。该函数的一般格式如下:

 pandas.concat(objs,axis=0,join='outer',ignore_index=False,keys=None,levels=None,names=None,verify_integrity=False,sort=False,copy=True)

concat()函数的常用参数:

参数描述
objs参与拼接的Pandas对象的列表
axis0或1。表示拼接的方向,默认为0,即纵向拼接
joininner”或"outer"。表示内连接(inner)还是外连接(outer)。默认为外连接
ignore_index表示是否忽略原索引值,如果为True,则忽略,如果为False(默认),则保留
  • 将两组数据实现纵向拼接

 data = pd.read_csv("../数据集/格力电器.csv")
 # 获取前3条数据中的前两列
 A = data.head(3)[["ts_code","trade_date"]]
 B = data.tail(3)[["ts_code","trade_date"]]
 all = pd.concat([A,B])
 print(all)
 ​
 #        ts_code  trade_date
 # 0    000651.SZ    20200930
 # 1    000651.SZ    20200929
 # 2    000651.SZ    20200928
 # 904  000651.SZ    20170105
 # 905  000651.SZ    20170104
 # 906  000651.SZ    20170103

数组all中沿用了数组A和数组B中列索引的值,要想从0开始重新设置索引,可以将参数ignore_index设置为True

 all = pd.concat([A,B],ignore_index)
 print(all)
 #        ts_code  trade_date
 # 0    000651.SZ    20200930
 # 1    000651.SZ    20200929
 # 2    000651.SZ    20200928
 # 3    000651.SZ    20170105
 # 4    000651.SZ    20170104
 # 5    000651.SZ    20170103

A数组和B数组的列名完全相同纵向拼接就是将相同列名的数据纵向堆叠在一起。

列名不完全相同:如数组A的列名为“A”和“B”,而数组B的列名是“B”和“C”。纵向拼接时,一般有以下两种拼接需求:

  • 只拼接列名相同的列数据,其余列都舍弃,即按列名的交集进行纵向拼接。
  • 所有列都不舍弃,即按列名的并集进行拼接。

设置concat()方法中的参数join为“inner”或“outer”就可以实现按列名的交集或并集进行拼接的功能。

 import pandas as pd
 data = pd.read_csv("../数据集/格力电器.csv")
 # 按列名的交集进行拼接:
 # 获取前3条数据中的前两列
 A = data.head(3)[["ts_code","trade_date"]]
 # 获取最后3条数据中的前两列
 B = data.tail(3)[["ts_code","open"]]
 all = pd.concat([A,B],join="inner")
 print(all)
 ​
 #        ts_code
 # 0    000651.SZ
 # 1    000651.SZ
 # 2    000651.SZ
 # 904  000651.SZ
 # 905  000651.SZ
 # 906  000651.SZ
 ​
 # 按列名的并集进行拼接:
 all = pd.concat([A,B],join="outer") # 默认为outer,可以不写

设置参数axis为01,即可设置横向或纵向拼接功能。

 import pandas as pd
 data = pd.read_csv("../数据集/格力电器.csv")
 # 获取前3条数据中的前两列
 A = data.head(3)[["ts_code","trade_date"]]
 # 获取最后3条数据中的前两列
 B = data.head(3)[["open","high"]]
 all = pd.concat([A,B],axis=1)
 print(all)
 ​
 #      ts_code  trade_date   open   high
 # 0  000651.SZ    20200930  53.16  53.42
 # 1  000651.SZ    20200929  53.40  53.61
 # 2  000651.SZ    20200928  54.12  54.45

横向拼接时,也会有以下两种横向拼接需求:

1、只拼接行名相同的行数据,其余行都舍弃,即按行名的交集进行横向拼接

 # 获取前3条数据中的前两列
 A = data.head(3)[["ts_code","trade_date"]]
 # 获取第3-5条数据中的第3-4列
 B = data.loc[2:4,["trade_date","high"]]
 # 按行名的交集进行横向拼接
 all = pd.concat([A,B],axis=1,join="inner")

2、所有行都不舍弃,即按行名的并集进行横向拼接

 all = pd.concat([A,B],axis=1)

4.3.2、merge拼接数据

有时需要根据一个或多个键将多个数据集的行连接起来。

Pandas中使用merge()函数实现类似SQL中的join操作功能,叫做合并数据

 import pandas as pd
 data = pd.read_csv("../数据集/格力电器.csv")
 # 获取前3条数据中的股票代码和交易日
 A = data.head(3)[["ts_code","trade_date"]]
 # 获取前3条数据中的交易日和收盘价
 B = data.head(3)[["trade_date","close"]]
 all = pd.merge(A,B,on="trade_date")

merge()函数的一般格式:

 merge(left,right, how= "inner",on= None,left_on= None,right_on= None,left_inde= False,right_indexalse,sort= False,suffixes= ("_x", "_y"),copy= None,indicator= False,validate= None)

merge()函数的常用参数:

参数描述
left要合并的数组A,DataFrame或series
right要合并的数组B,DataFrame或series
how数据的连接方式,有内连接(inner)、外连接(outer)、左连接(left)和右连接(right),默认为inner
on两个数组的主键(必须一致)
left_onleft数组用于连接的列名,默认为None
right_onright数组用于连接的列名,默认为None(left_on和right_on主要用于连接2个列名不同的数组)
left_index是否使用left数组的行索引作为连接键,默认为False
right_index是否使用right数组的行索引作为连接键,默认为False
sort是否根据连接键对合并后的数据进行排序,默认为False
suffixes存在相同列名时在列名后面添加的后缀,默认为('x',"y")
copy默认为True,表示将数据复制到新数组中,设置为False可以提供性能
indicator显示合并结果中的数据来自那个数组

merge()函数也有四种连接方式通过how来设置连接方式。

 # 使用内连接合并两个数组的功能。其他方式的功能,只需要更改merge()参数how即可
 A = pd.DataFrame([[1,2],[3,4]],index=[0,1],columns=["A","B"])
 B = pd.DataFrame([[4,11],[6,13]],index=[2,3],columns=["B","C"])
 all = pd.merge(A,B,on="B",how="inner")
 print(all)
 ​
 # 将左右数组的行索引作为唯一连接键进行数组合并
 all = pd.merge(A,B,left_index=True,right_index=True,how="inner")

4.3.3、重叠数据的合并

若出现两条数据的内容几乎一致,但某些特征在一张表上是完整的,而在另一张表中有缺失,可以用DataFrame中的combine_first()方法进行重叠数据的合并。

 A = pd.DataFrame([[1,2],[3,4],[pd.NA,13]],index=[0,1,2],columns=["A","B"])
 B = pd.DataFrame([[pd.NA,4],[6,12]],index=[1,2],columns=["A","B"])
 # 重叠数据的合并
 all = A.combine_first(B)
 print(all)
 ​
 #    A   B
 # 0  1   2
 # 1  3   4
 # 2  6  13

conbine_first()方法有以下特点:

  • combine_first()方法是DataFrame数组自带的方法
  • 合并时,除了列名外,行索引也是其中的一个连接键
  • 如果待重叠合并的两个数组相同位置上的值不同,如数组A的12与数组B的12,则结果以数组A中的值为准

4.4、添加数据

4.4.1、字典形式的赋值

使用data[key]=value的形式可以添加一列数据到数据集的最后,这里的value可以是一个list、ndarray一维数组、Series数组,也可以是单个值。

 import numpy as np
 import pandas as pd
 data = pd.read_csv("../数据集/格力电器.csv")
 # 字典形式赋值
 data["bias"] = np.arange(len(data)) # ndarray数组(0,1,2...)

如新增的列中各个值相同,则直接赋值即可:

 data["bias"] = 1 # 设置相同的值

4.4.2、使用insert()函数

DataFrame的insert()函数,可以选择按行插入或按列插入,可以选择插入的位置

  • 第一个参数设置新列插入的位置的索引值
  • 第二个参数设置列名
  • 第三个参数设置插入列的值

 # 在数据的最前列插入一列全为1的数据
 data.insert(0,"bias",1) # 最前列插入一列列名bias。值为1的数据
 ​
 # 在第二列插入一列列名为bias、值递增的数据
 data.insert(1,"bias",np.arange(len(data)))

4.4.3、修改数据

方法是将要修改的数据提取出来,重新赋值为新的数据

 # 将股票代码(ts_code)中的字符去掉(000651.SZ->000651)
 import pandas as pd
 data = pd.read_csv("../数据集/格力电器.csv")
 data["ts_code"] = "000651"
 ​
 # 将当天收盘价(close)低于50的成交额(amount)设定为0
 data.loc[data["close"]<50,"amount"] = 0 # loc函数提取数据

4.4.4、删除数据

DataFrame提供的drop()函数可以删除某列或某行的数据,其语法:

 DataFrame.drop(labels= None,axis= 0,index= None, columns= None,level= None,inplace= False,errors= "raise",

drop()函数的常用参数:

参数描述
labelsstr或array型,表示要删除的行或列的名称
axis表示要操作的轴向:0/index表示按行、i/columns表示按列
index按行删除
columns按列删除
inplace表示操作是否对原数据生效。默认为True
errors"ignore"或"raise",前者不会报错,只删除存在的行或列。默认为"raise"
 # 按列删除:
 data.drop(labels=["ts_code","trade_date"],  # 删除的行或列的名称
           axis=1, # 操作的轴向,1:按列删除
           inplace=True # 对原数据生效
           )
 # 按列删除简洁版:
 data.drop(columns=["ts_code","reade_date"],# 删除列的代替写法
          inplace=True)  # 对原数据生效

如果将参数inplace设置为False,则data中的数据不会有任何变动,因此此时它会复制一份data对象,所有操作针对的都是该复制对象,

如果只想删除某一列的数据,还可以使用pop()函数del命令实现:

 data.pop("ts_code") 
 del data{"ts_code"}

五、数据深度处理

“脏”数据:

  • 多余的数据:一些诸如“编号”之类的数据。
  • 重复的数据
  • 带有缺失值的数据:字段值缺失或着为空,会直接导致统计分析出错
  • 非数值类型数据:将字符串这种非数值型数据无法参与数学计算。

5.1、数据去重

处理重复数据有三种方式:

  • 保留第一个
  • 保留最后一个
  • 全不保留

Pandas的DataFrame提供了drop_duplicates()函数实现重复数据的检测和处理:

 DataFrame.drop_duplicates(subset=None,keep='first',inplace=False,ignore_index=False)

drop_duplicates()函数的常用参数:

参数描述
subset列名,表示在指定列中查找重复数据,默认为None,表示查找全部列
keep表示对重复数据的处理方式:first:保留第一个(默认)last:保留最后一个False:只要有重复数据都不保留
inplace表示是否在原表上操作。默认为False
 # 如果数据完全一样,则全部删除
 data.drop_duplicates(keep=False,inplace=True)
 ​
 # 如果第1列和第2列数据完全一样,则认定为重复数据,只保留第1条数据。
 data.drop_duplicates(subset=["ts_code","trade_date"],keep="first",inplace=True)

5.2、缺失值处理

拿到数据先检测数据中是否存在缺失值,如果存在缺失值,先对缺失值处理。检测缺失值的方法

 DataFrame.isnull()  # 检测是否有缺失值
 DataFrame.notnull() # 检测是否没有缺失值

5.2.1、删除法*

删除法就是删除缺失值所在的行或列。使用dropna()函数实现:

DataFrame.dropna(axis= 0,how='any',thresh=None, subset= None,inplace= False)

dropna()函数的常用参数:

参数描述
axis0或1.表示轴向,0:按行删除。1:按列删除
how删除方式:any:只要有缺失值就执行删除操作(默认)、all:当且仅当全部为缺失值才执行删除操作
subset去重的列/行。默认为None。即所有行/列,array型
inplace表示是否在原表上操作。默认为False

5.2.2、替换法*

替换法就是使用某个值来填充缺失值。使用fillna()函数实现:

 DataFrame.fillna(value=None,method=None,axis=None,inplace=False,limit=None,downcast=None)

fillna()函数的常用参数:

参数描述
value用于填充的值
method填充方式:pad/ffill:选择上一个非缺失值。backfill/bfill:选择下一个非缺失值
axis0或1。0:按行填充。1:按列填充
inplace表示是否在原表上操作。默认为False

5.2.3、插值法

插值法就是通过两点估计中间点的值。Pandas使用interpolate()函数实现插值法填充缺失值功能:

 DataFrame.interpolate(method: str = "linear",axis= 0,limit= None,inplace= False,limit_direction= None,limit_area= None,downcast= None,**kwargs)

interpolate()函数的常用参数“

参数描述
method使用的部分插值算法:'linear':线性(默认)。'time':在以天或者更高频率的数据中插入给定时间间隔长度的数据。'index'、'values':使用索引对应的值。'pad':使用现有值
axis0或1
limit设置最多可以向连续多少个NaN中填充其他数值,该值必须大于0
inplace表示是否在原表上操作。默认为False
 # 使用固定值-99填充所有缺失值:
 import pandas as pd
 data = pd.read_csv("../数据集/格力电器_缺失值.csv")
 data.fillna(-99,inplace=True)
 ​
 # 使用50填充开盘价(open)的缺失值,使用55填充最高价(high)的缺失值:
 my_dict = {"open":50,"high":55}
 data.fillna(my_dict,inplace=True)
 ​
 # 使用开盘价(open)和最高价(high)的平均值填充当前列的缺失值:
 data["open"].fillna(data["open"].mean(),inplace=True)
 data["high"].fillna(data["high"].mean(),inplace=True)
 ​
 # 使用上一个非缺失值填充开盘价(open)中的缺失值
 data["open"].fillna(method="ffill",inplace=True)
 ​
 # 删除存在缺失值的整列数据
 data.dropna(axis=1,how="any",inplace=True)
 ​
 # 使用插值法实现对缺失值的填充
 data.interpolate(inplace=True)

5.3、数据转换

通常获取到的数据会包含大量非数值型数据。Pandas通过哑变量(Dummy Variable)实现将字符串转换为数值型的功能。哑变量也叫虚拟变量,引入哑变量的目的是将不能够定量处理的变量量化。根据这些因素的属性类型构造的只取0或1的人工变量通常称为哑变量。

哑变量处理的特点:

  • 若一个类别特征有m个取值,则哑变量处理后就变为m个二元特征。
  • 特征值互斥,每次只有一个被激活(’1‘表示激活)。
  • 数据变成了稀疏矩阵的形式,加快了算法模型的运算速度。

Pandas使用get_dummies()函数实现哑变量处理的功能:

 DataFrame.get_dummies(data,prefix=None,prefix_sep= "_",dummy_na= False,columns=None,sparse= False,drop_first= False,dtype= None)

get_dummies()函数的常用参数:

参数描述
data需要进行哑变量处理的数据
prefix哑变量处理后列名的前缀。默认为None
prefix_sep前缀连接符,默认为"_"
dummy_na是否为NaN添加一列,默认为False
columns需要编码的列名,默认为None,表示对所有列进行编码
drop_first是否通过从k个分类级别中中删除第一级来获得k-1个分类级别。默认为False
dtype生成的新列的数据类型,默认为Uint8
 import pandas as pd
 data = pd.read_csv("../数据集/格力电器_哑变量.csv")
 data=pd.get_dummies(data,prefix=["satatus"],columns=["status"])
 print(data)
 ​
 #      ts_code  trade_date   open   high  satatus_上涨  satatus_下跌  satatus_平盘
 # 0  000651.SZ    20200927  53.40  53.61        True       False       False
 # 1  000651.SZ    20200928  53.40  53.61       False        True       False
 # 2  000651.SZ    20200929  54.35  54.61       False       False        True
 # 3  000651.SZ    20200930  53.16  53.42        True       False       False

六、统计分析

6.1、汇总统计

常用汇总统计方法:(默认按列进行统计,要按行进行统计们可以设置参数axis=1)

方法描述方法描述
count计算分组中非NA值的数量sum计算非NA的和
mean计算非NA值的算术平均值median计算非NA的中位数
std计算非NA的标准差var计算非NA的方差
min计算非NA的最小值max计算非NA的最大值
describe一次性产生多少个汇总统计
 # 求数据集中的收盘价、成交量的最大值即最小值:
 import pandas as pd
 data = pd.read_csv("../数据集/格力电器.csv")
 data1 = data[["close","vol"]]   # 获取收盘价和成交量
 data1.max() # 按列求最大值
 data1.min() # 按列求最小值
 data1.describe()    # 多种统计数据

6.2、groupby:数据分组聚合

若想统计每年的平均收盘价、平均成交额等统计信息,就必须将数据集按年份分组,每组分别计算平均收盘价、每天平均成交额等统计信息。

DataFrame提供的groupby()函数可以按照指定的特征进行分组,再分别计算各组的统计信息:

 # 使用groupby()函数实现年平均收盘价和平均日成交额:
 year = data["trade_date"].astype(str)   # 提取前4位,即年份
 year = year.str[0:4]                    # 添加到数据集中
 data["year"] = year                     # 按年份分组
 group = data[["year","close","amount"]].groupby(by="year")  # 求得平均值
 print(group.mean())

groupby()函数的语法

 DataFrame.groupby(by=None, axis=0,level=None,as_index=True,sort=True,group_keys=True,squeeze=<object object>,observed=False,dropna=True)

groupby()函数的常用参数

参数描述
by用于确定进行分组的依据,必选
axis表示操作的轴向,默认对列进行操作,即取值为0
sort表示是否对分组标签进行排序。默认为True
group_keys表示是否显示分组标签的名称。默认为True
squeeze表示是否在允许的情况下对返回数据进行降维。默认为False

该方法返回一个包含分组信息的DateFrameGroupBy类的对象,调用该对象中的各种方法,就可以得到分组统计的值。

DateFrameGroupBy类的统计函数:

函数描述函数描述
count计算分组中非NA值的数量sum计算非NA值的和
mean计算非NA值的平均值median计算非NA值的中位数
std计算非NA值的标准差var计算非NA值的方差
min计算非NA值的最小值max计算非NA值的最大值
prod计算非NA值的积first、last获取第一个和最后一个非NA值

6.3、agg:数据聚合

在统计数据时,不同特征值的统计策略也不相同。

事实上,针对不同特征值,可以使用Pandas或者NumPy的数据统计函数分别求得:

 # 1、求得数据集中收盘价、成交额的平均值和最大值
 c_a_mean = data[["close","amount"]].mean()  # 收盘价和成交额的平均值
 c_a_max = data[["close","amount"]].max()    # 收盘价和成交额的最大值
 ​
 # 2、求得数据集中收盘价的平均值,成交额的最大值
 c_mean = data["close"].mean()   # 收盘价的平均值
 c_max = data["amount"].max()    # 成交额的最大值
 ​
 # 3、求得数据集中收盘价的平均值,成交额的最大值和最小值
 c_a_mean = data["close"].mean() # 收盘价的平均值
 o_max = data["open"].max()  # 成交额的最大值
 o_min = data["open"].min()  # 成交额的最小值

上述方法每次只能统计一种数据。使用DataFrame的 agg()函数可以设置不同特征的不同统计需求,一次求出:

agg()函数的常用参数:

参数描述
func应用于每行或每列的函数,可以是list、dict或函数
axis表示操作的轴向,默认对列进行操作,取值为0
 # 例子:#求得数据集中收盘价、成交额的平均值和最大值
 result1 = data[["close","amount"]].agg([np.mean,np.max])
 ​
 # 求得数据集中收盘价的平均值,成交额的最大值
 result2 = data.agg({"close":np.mean,"amount":np.max})
 ​
 # 求得数据集中收盘价的平均值,成交额的最大值和最小值
 result3 = data.agg({"close":np.mean,"amount":[np.max,np.min]})

另外,有些数据是要分组后再进行统计的:

 # 将数值型日期转换为字符串
 year = data["trade_date"].astype(str)
 # 提取前4位,即年份
 year = year.str[:4]
 # 添加到数据集
 data["year"] = year
 # 按年份分组
 group = data[["year","close","amount"]].groupby(by="year")
 # 求各年度收盘价与成交额的平均值和最大值
 r1 = group.agg([np.mean,np.max])
 print(r1)
 ​
 # 其结果为
 #           mean   amax          mean          amax
 # year                                              
 # 2017  36.024486  47.80  2.513256e+06  5.808663e+06
 # 2018  44.438230  57.40  2.607493e+06  1.712054e+07
 # 2019  53.539958  65.58  2.461973e+06  1.819573e+07
 # 2020  57.894426  69.88  3.209122e+06  8.947222e+06
 ​
 # 如果想获取成交额(amount)的平均值和最大值:
 r1["amount"]
 ​
 # 获取成交额的年平均值:
 r1["amount"]["mean"]    # 成交额的年平均值
 r1["amount"]["mean"]["2018"]    # 2018年成交额的平均值。注意2018要加双引号
 ​
 # 求各年度收盘价的平均值,成交额的最大值
 r2 = group.agg({"close":np.mean,"amount":np.max})
 ​
 # 求各年度收盘价的平均值,成交额的最大值和最小值
 r3 = group.agg({"close":np.mean,"amount":[np.max,np.min]})

6.4、apply:数据聚合

agg()方法的优势在于它可以根据不同特征制定不同规则的计算策略。当所有行或列使用的统计规则都一样时,就可以使用apply()函数实现。apply()方法传入的函数只能够作用整个DataFrame或者Series,agg()函数可以对不同字段设置不同函数来获取不同结果。

 DataFrame.apply(func.axis=0,raw=False,result_type=None,args=(),**kwds)

apply()函数的常用参数:

参数描述
func应用于每行或每列的函数,可以是list、dict或函数
axis表示操作的轴向,默认对列进行操作,即取值为0
raw表示是否将行或列作为Series或ndarray传递给函数,默认为False,即将每个行或列作为序列传递给函数
result_type表示apply()函数的返回类型(仅在axis=1时起效)。'expand':结果作为新列追加。'reduce':返回一个Series。'broadcast':将结果广播到DataFrame的原始形状,保留原始索引和列。None:默认值。当result_type设置为None时,apply()函数的返回类型与func参数的返回类型一致。
 import pandas as pd
 data = pd.read_csv("../数据集/格力电器.csv")
 # 求得数据集中收盘价、成交额的平均值
 c_a_mean = data[["close","amount"]].apply(np.mean)
 ​
 # 求得数据集中收盘价、成交额的平均值和最大值
 c_a_mean = data[["close","amount"]].apply([np.mean,np.max])
 ​
 # 求得数据集中收盘价、成交额的平均值
 # 函数作为参数求平均值
 def get_mean(data):
     return np.mean(data)
 c_a_mean = data[["close","amount"]].apply(get_mean)
 ​
 # 求各年度收盘价与成交额的平均值
 year = data["trade_date"].astype(str)   # 提取前4位,即年份
 year = year.str[0:4]    # 添加到数据集中
 data["year"] = year # 按年份分组
 group = data[["year","close","amount"]].groupby(by="year")  # 求各年度收盘价与成交额的最大值
 r1 = group.apply(np.mean)

DataFrameGroupBy对象也集成了apply(),使用方法与agg()相近,区别在于使用agg()能够实现对不同字段应用不同的函数,而

6.5、transform:数据转换

transform()函数可以按行或者列对整个DataFrame的所有元素进行操作,transform()函数的参数:

参数描述
func应用于每行或每列的函数,可以是list、dict或函数
axis表示操作的轴向。默认对列操作
 # 将收盘价和成交额变为原来的两倍
 result = data[["close","amount"]].transform(lambda x:x*2)
 ​
 # 收盘价和成交额减去各自的平均值,得到与平均值的差额
 result = data[["close","amount"]].transform(lambda x:x-x,mean())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小李学不完

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值