Python数据分析与应用--pandas统计分析基础(知识点)
一、Pandas模块介绍
- Pandas模块是Python的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据(数值型、文本型、时间序列)。
- Pandas建立在Numpy之上。
- 提供数据清洗功能,可用于数据挖掘和数据分析。
- 支持类似SQL的数据增、删、查、改,拥有丰富的数据处理函数。
支持时间序列分析功能;支持灵活处理缺失数据等。
二、Pandas数据结构
1、Series对象(带标签的数组)
2、DataFrame对象

3、Series、DataFrame
3.1Series对象
pandas.Series( data, index, dtype, copy)
说明:data可以是标量、列表、迭代对象、字典、ndarray等对象。
import pandas as pd
import numpy as np
s1 = pd.Series(5,index=[1,2,3,4],dtype='str') #标量,设置了索引与类型
print(s1)
s2 = pd.Series([10,20,30,40]) #列表
print(s2)
s3 = pd.Series(range(10,20)) #迭代对象
print(s3)
s4 = pd.Series({'a':'H1','b':'H2','c':'H3'}) #字典,键为索引
print(s4)
s5 = pd.Series(np.array(['x','y','z'])) #ndarray
print(s5)
3.2 DataFrame创建:
Pd.DataFrame(data, index, columns, dtype, copy) #构造DataFrame数据框架
说明:(1)从列表、字典、ndarray等对象转化为DataFrame
import pandas as pd
info = {'name':'张三','age':20,'tel':'13500100203','hobby':'上网,打游戏,运动'}
sd = pd.Series(info)
df1 = pd.DataFrame(sd)
df2 = pd.DataFrame(info,columns=['name','age','tel','hobby'],index=[0])
print(df1)
print(df2)
(2)从文件(文本、表格、数据库)中读取数据转化为DataFrame。
三、读取不同的数据源中的数据(关系型)
1、读取文本文件
Pandas读取csv/tsv/txt文件使用read_csv或read_table实现。
函数格式:read_csv(参数) 或read_table(参数)

(1)read_csv和read_table之间的区别
函数pd.read_csv和pd.read_table的内容相同,只是默认分隔符不同。在read_csv中“逗号,”作为定界符,在read_table中定界符为“\ t”。如果既不是逗号也不是制表符,则可以通过参数(sep或delimiter)设置区分符。
(2)读取没有标题的CSV
- 如果未设置任何参数,则将第一行识别为标题并将自动分配列名columns。
11,12,13,14
21,22,23,24
31,32,33,34
df = pd.read_csv('simple.csv')
print(df.columns)
如果header = None,则将为列名列分配一个序号(0,1,2,3,……)
可以将任意值设置为列名,参数为names=(‘A’,‘B’,‘C’,‘D’)。通过列表或元组指定。
df_names = pd.read_csv('sample.csv', names=('A', 'B', 'C', 'D'))
print(df_names)
(3) 读取有标题的CSV
a,b,c,d
11,12,13,14
21,22,23,24
31,32,33,34
指定标题的行号从0开始,例如header = 0。由于默认值为header = 0,因此如果第一行是header,则可以获得相同的结果。即有标题的csv,header参数是否设置为0,都会将1行设为标题行,但如果设置为其它值,则该行做为标题行。
df_header_0 = pd.read_csv('sample_header.csv', header=0) #header参数设置可省略
(4)读取有index和标题行的CSV
,a,b,c,d
ONE,11,12,13,14
TWO,21,22,23,24
THREE,31,32,33,34
如果未指定任何内容,则不会识别索引列。
pddata= pd.read_csv('sample_header_index.csv')
print(pddata)
如果要指定要用作索引的列的列号,从0开始,设置index_col = 0。
df_header_index_col = pd.read_csv('sample_header_index.csv',index_col=0)
print(df_header_index_col.index)
(5)指定(选择)要读取的列
要仅读取特定的列,请使用usecols参数。 指定要在列表中读取的列号。即使只有一列,也要使用列表。
df_usecols = pd.read_csv('sample.csv',header=None, usecols=[1, 3])
print(df_usecols)
也可以按列名而不是列号指定
df_header_usecols = pd.read_csv('sample_header.csv',usecols=['a', 'c'])
print(df_header_usecols)
在没有特定列的情况下时,使用匿名函数(lambda表达式)很方便。尤其是当您要从具有许多列的文件中排除少量列并读取它们时,比指定要读取的大量列号要容易得多。
df_header_usecols = pd.read_csv('sample_header.csv', usecols=lambda x: x not in ['a', 'c'])
print(df_header_usecols)
(6)跳过(排除)行的读取
要跳过(排除)特定行并读取它们,使用参数skipprows。 如果将整数传递给跳过行,那么将跳过那么多行的文件开头。下面的例子是跳过前两行。
df_none = pd.read_csv('sample.csv', header=None, skiprows=2)
print(df_none)
可以指定要跳过的行号列表。也可以使用lambda表达式设置指定行。
df_none_skiprows = pd.read_csv('sample.csv',header=None, skiprows=[0, 2])
print(df_none_skiprows)
请注意,即使指定了索引,也无法通过行名指定skipprows。
(7)参数dtype中指定列类型(以字典格式设置)
,a,b,c,d
ONE,1,"001",100,x
TWO,2,"020",,y
THREE,3,"300",300,z
df_str_col = pd.read_csv(r'sample_header_index_dtype.csv',index_col=0, dtype={'a':int,'b': str, 'c': float,'d':object})
print(df_str_col)
print(df_str_col.dtypes)
2、读取Excel表格中的数据
pandas库提供了read_excel()函数读取“xls”和“xlsx”两种Excel文件,基本使用格式:
pandas.read_excel(参数列表)
说明:参数列表中除了sheet_name参数与read_csv不同,其它用法一致。sheet_name接收str、int、list或None。表示Excel表内数据的分表位置。默认为0,可使用[0,1,'学生表']这样的格式设置该参数。

3、读取数据库中的数据
(1)读数据库数据
- read_sql_table(参数)函数只能读取数据库的某一个表格,不能实现查询的操作。
- read_sql_query(参数)函数则只能实现查询操作,不能直接读取数据库中的某个表。
- read_sql(参数)函数是两者的综合,既能够读取数据库中的某一个表,也能够实现查询操作。

from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/musicdatas?charset=utf8')
print(engine)
musicdata = pd.read_sql('musicdata',con = engine)
print(musicdata)
musicdata.to_sql('musicdatatest',con=engine,index=False,if_exists='replace')
list = pd.read_sql_query('show tables',con=engine)
print(list)
(2)写入数据库数据
函数名称:pd.to_sql(参数)
import pandas
# 使用sqlalchemy连接数据库
import sqlalchemy
sqlalchemy_db = sqlalchemy.create_engine("mysql+pymysql://root:123456@localhost:3306/jd_data")
# sql查询语句
sql = "select * from to_sql_demo"
# 模拟写入数据库中的数据
data = {'A': [1, 2, 3, 4, 5],
'B': [6, 7, 8, 9, 10],
'C': [11,12,13,14,15]}
data__frame = pandas.DataFrame(data) # 创建DataFrame对象
# 向数据库中写入模拟数据data
data__frame.to_sql('to_sql_demo',sqlalchemy_db,if_exists='append')
# 通过read_sql()函数读取数据库信息
read_sql_data = pandas.read_sql(sql=sql,con=sqlalchemy_db)
print('\n通过read_sql()函数读取数据库信息如下:\n', read_sql_data
四、Series、DataFrame应用
(1)Series属性
- axes:以列表的形式返回所有行索引标签
- dtype:返回对象的数据类型。
- empty:返回一个布尔值,判断数据对象是否为空
- ndim:返回输入数据的维数
- size:返回输入数据的元素数量
- values:以 ndarray 的形式返回 Series 对象
- index:返回一个索引的取值
(2)DataFrame属性
- values:DataFrame所有行的值
- index:DataFrame行索引
- colums:DataFrame列名
- dtypes:DataFrame指定列数据类型
- size:DataFrame元素的个数
- ndim:DataFrame维度
- shape:DataFrame形状
- T:实现DataFrame转置
(3)Series查询操作
使用索引、切片方式
info = {'name':'张三','age':20,'tel':'13500100203','hobby':'上网,打游戏,运动'}
sd = pd.Series(info)
print(sd['tel'])
print(sd[1:4])
print(sd[[2,3]])
(4)DataFrame查询操作
使用索引、切片方式
DataFrame名称[行索引编号范围或名称][列索引范围或列名]
DataFrame名称[列索引范围或列名][行索引范围或名称]
print(sql_table_data['id'][1:5])
print(sql_table_data[['id','book_name']][1:5])
print(sql_table_data[1:5][['id','book_name']])
print(sql_table_data[1:5])
使用iloc(iat)或loc(at)函数
使用loc()方法和iloc()方法可以对DataFrame进行多种操作:单列切片、多列切片、取出DataFrame中的任意数据。
DataFrame.loc[行索引名称或条件, 列索引名称]
DataFrame.iloc[行索引编号位置, 列索引编号位置]
loc()方法更加灵活多变,代码的可读性更高;iloc()方法的代码简洁,但可读性不高。在数据分析工作中具体使用哪一种方法,应根据情况而定,大多数时候建议使用loc()方法。
print("打印第1-3列所有行数据",sql_table_data.iloc[:,[0,1,2]])
print("打印第1-3列所有行数据",sql_table_data.loc[:,['id','book_name','jd_price']])
print("打印第1-3列前10行数据",sql_table_data.iloc[0:10,[0,1,2]])
print("打印第1-3列前10行数据",sql_table_data.loc[0:10,['id','book_name','jd_price']])
(3)DataFrame基本操作—增、删、改
- 重命名列标签
DateFrame.rename(columns={k1:v1,k2:v2....}):重命名部分列标签
DateFrame.columns=['新列名',.......]:重命名全部列标签
- 删除列
DateFrame.drop(columns=’要删除的列名’)
- 更改数据
操作方法:采用索引或切片的方式将数据提取出来,再赋予新的值即可。
- 新增列
操作方法:创建一个新的列索引,对该列索引赋值即可。
import pandas as pd
stu_data = {'A':['张三','李四','王五','何六','谢七','陆九'],
'B':['男','女','男','女','女','男'], 'C':['20000302','19990416','20011214','20000812','20010708','20001017'],
'D':[173,162,182,159,162,178],
'E':['无','无','','','','无']
}
student = pd.DataFrame(stu_data)
print(student)
#修改C列的数据类型为'datetime64'
student['C'] =student['C'].astype('datetime64')
print(student.dtypes)
#修改列标签
student.columns = ['姓名','性别','出生日期','身高','备注']
print(student)
#修改备注列中所有空值为"暂无"
student.loc[student['备注']=='',['备注']]='暂无'
print(student)
#新增"专业"列,数值为"数据科学与大数据技术"
student['专业']='数据科学与大数据技术'
print(student)
(4)DataFrame特征数据统计----数值型数据
- 最大值、最小值、求和、平均值、非空值数目(count)。
- 方差(var):衡量一组数据的离散程度。
- 标准差(std): 衡量一组数据的离散程度。
- 极差(ptp):用于统计资料中变异量数,其最大值与最小值之间的差距。
- 协方差(cov):衡量两个变量在变化过程中,是同方向变化还是反向变化,程序如何?(协方差值越大,变量同向程度越大)
- 标准误差(sem):反映测量的精密度(观测值与真实值之间的误差)
- 偏度(skew):偏度与峰度用于检测数据集是否符合正态分布。偏度衡量随机变量概率分布的不对称性。(正态分布偏度为0,偏度大于0,分布右偏,偏度小于0,分布左偏。)
- 峰度(kurt):峰度是研究数据分布陡峭或平滑的统计量。(正态分布峰度为0,均匀分布的峰度(值为-1、-2,平缓),指数分布的峰度(值为5、6以上,陡峭))。
- 中位数(median):按值从低到高排位正中间的数作为中位数。如果个数为偶数则取中间两个数的均值。
- 分位数(quantile):将数值从小到大分为四等份,处于三个分割点(25%、50%、75%)位置的数值就是四分位数。
import pandas as pd
score_data = pd.read_excel(r'data\test_score.xlsx')
print("查看各科平均分:")
print('数学:',round(score_data['数学'].mean(),2))
print('语文:',round(score_data['语文'].mean(),2))
print('英语:',round(score_data['英语'].mean(),2))
五、DataFrame处理时间序列数据
在多数情况下,对时间类型数据进行分析的前提就是将原本为字符串的时间转换为标准时间类型。pandas继承了NumPy库和datetime库的时间相关模块,提供了以下几个常用的函数。
- date_range():指定时间的起始start和结束范围end、时间间隔freq、数据数量periods等参数。主要用于生成一个固定频率的时间索引,数据类型为:DatetimeIndex。保存在DataFrame对象中的每一个时间数据,都会被转换为Timestamp类型的数据。可以调用对应的属性获得日期中的部分数据。
import pandas as pd
date1 = pd.date_range(start='20230301',freq='D',periods=10)
date2 = pd.date_range(end='20230301',freq='M',periods=10)
print(date1[0].year) #输出date1中第一个日期的年份
y_m = [(i.year,i.month) for i in date2] #获取date2日期中的年、月
print(y_m)
- to_datetime():用于实现将规范或不规范的时间数据转换为标准的datetime类型数据。可以使用errors参数对无效数据进行解析,参数值设置有:接收“ignore”、“raise”、“coerce”。
import pandas as pd
date1 = pd.to_datetime('2023 03 08 9:00')
print(date1)
Timedelta():根据一个指定时间计算未知的时间,Timedelta()括号内参数可以指定多个参数,如周weeks、天days、小时hours等。
import pandas as pd
date1 = pd.to_datetime('2023 03 08 9:00')
print(date1)
print(date1.dayofweek)
date2 = date1+pd.Timedelta(weeks=5,days=3)
print(date2)
print(date2.dayofweek)
- query():Pandas提供此函数可以实现内容(包括时间)的查询、修改列、创建新列。
六、DataFrame使用分组进行组内计算

(1)拆分数据: groupby方法
groupby()方法的常用参数及其说明:

分组后的结果并不能直接查看,而是被存在内存中,输出的是内存地址groupby功能生成的是多个tuple对象,每个tuple对象有两个元素,第一个元素是分类的名字,第二个元素是该分类的所有行构成的DataFrame,groupby对象常用的描述性统计方法(describe)及说明如下表:

(2)聚合数据:agg(或aggregate)方法、apply方法、transform方法
区别:
agg:能够针对不同特征应用不同的函数。
apply:所有(相同)特征只能应用某几个函数,不能分特征分别统计。
transform:只能对每一列进行计算,所以在groupby()之后,.transform()之前是要指定要操作的列,该方法会将统计值在dataframe中所有涉及的rows都显示出来。还可用于数据标准化处理(归一化)。通过标准化处理,可以使得不同的特征具有相同的尺度(Scale)。简言之,当原始数据不同维度上的特征的尺度(单位)不一致时,需要标准化步骤对数据进行预处理。
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': list('XYZXYZXYZX'),
'B': [1, 2, 1, 3, 1, 2, 3, 3, 1, 2],
'C': [12, 14, 11, 12, 13, 14, 16, 12, 10, 19]})
print(df)
group = df.groupby(by='A')
for i,data in group:
print(i,data)
### agg方法:对聚合后B、C列各自进行汇总运算
print(group['B','C'].agg({'B':np.mean, 'C': np.std}))
### agg方法:对不同列(B、C列)各自进行多项统计汇总运算
print(group.agg({'B':[np.mean, 'sum'], 'C':['count',np.std]}))
### apply方法:内置函数不能使用,如'count',不能针对各特征分别统计
print(group['B','C'].apply(np.mean))
print(group['B'].apply(lambda x:x.count()))
###transform方法:只能对每一列进行计算,所以在groupby()之后,.transform()之前是要指定要操作的列
print(group.transform(lambda x:x.count()))
注意:agg()+python内置方法的计算速度最快,其次是transform()+python内置方法。而 transform() 方法+自定义函数 的组合方法最慢。python自带的stats统计模块在pandas结构中的计算也非常慢!
七、DataFrame创建透视表与交叉表

- crosstab只能使用pd.crosstab()的形式,而pivot_table可以同时使用DataFrame.pivot_table()和pd.pivot_table()的形式。使用pd.pivot_table()的时候,需要使用data参数指定数据集。
- 因为pivot_table方法关联到了具体的DataFrame,所以其方法中的参数index、columns、values可以直接写DataFrame的列名,而crosstab中的同名参数就必须使用Series、list等数据类型来指定计算的数据集。
- pivot_table方法可以填充缺失值。
(1)pivot_table函数创建透视表
透视表是各种电子表格和其他数据分析软件中一种常见的数据汇总形式,可根据一个或多个建对数据进行聚和,并根据行或列的分组键将数据划分到各个区域。利用pivot_table函数可以实现创建透视表。
函数格式:pd.pivot_table(参数)

使用pivot_talbe()函数时,若不特殊指定聚合函数的参数aggfunc,会默认使用numpy.mean进行聚合运算,numpy.mean会自动过滤掉非数值类型数据。读者可以通过指定aggfunc参数来修改聚合函数。和groupby()方法分组相同,pivot_table()函数在创建透视表的时候分组键index可以有多个。当全部数据列数很多时,若要只显示自己关心的列,则可以通过指定values参数来实现。
import pandas as pd
import numpy as np
sale_data = pd.read_excel(r'data\sales.xlsx',sep=',',encoding='GB2312')
print(sale_data)
print(pd.pivot_table(sale_data,index='大类',aggfunc='count',values='产品名称'))
print(pd.pivot_table(sale_data,index='大类',columns='小类',values='价格_元',aggfunc=np.sum,fill_value=0))
(2)crosstab函数创建交叉表
交叉表是一种特殊的透视表,主要用于计算分组频率。利用pandas提供的crosstab函数可以制作交叉表。函数格式与pivot_tables相似,多了一个常用参数normalize(布尔值,{'all','index','columns'}或{0,1},默认为False)。 通过将所有值除以值的总和进行归一化。
import pandas as pd
import numpy as np
student_data = pd.read_excel(r'data\student.xlsx')
print(pd.crosstab(index=student_data['班级'],columns=student_data['性别'],
values=student_data['大学英语'],aggfunc='mean'))
print(pd.crosstab(index=student_data['班级'],columns=student_data['性别'],
values=student_data['大学英语'],aggfunc='mean',normalize='columns'))
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)