第四章 Pandas 统计分析基础(下)

简介: 第四章 Pandas 统计分析基础(下)

4.4 Pandas 数据运算

4.4.1 算术运算

Pandas的数据对象在进行算术运算时,如果有相同索引则进行算术运算,如果没有,则会自动进行数据对齐,但会引入缺失值。


【例 4 - 35】 Series 相加

obj1 = pd.Series([5.1 , -2.6, 7.8, 10], index = ['a', 'c', 'g', 'f'])
print('obj1:\n', obj1)
obj2 = pd.Series([2.6, -2.8, 3.7, -1.9], index = ['a', 'b', 'g', 'h'])
print('obj2:\n', obj2)
print(obj1 + obj2)

2689339892324622964c894a10aa7d6a.png


【例4-36】DataFrame类型的数据相加
a = np.arange(6).reshape(2, 3)
b = np.arange(4).reshape(2, 2)
df1 = pd.DataFrame(a, columns = ['a', 'b', 'e'], index = ['A', 'C'])
print('df1:\n', df1)
df2 = pd.DataFrame(b, columns = ['a', 'b'], index = ['A', 'D'])
print('df2:\n', df2)
print('df1 + df2:\n', df1 +df2)

a499e5070ed14ca8bcfad42e2ad7d4e9.png


4.4.2 函数应用哈映射

已定义好的函数可以通过以下三种方法应用到数据:

§ 1. map函数:将函数套用到Series的每个元素中;

 § 2. apply函数,将函数套用到DataFrame的行或列上,行与列通过axis参数设置;

 § 3. applymap函数,将函数套用到DataFrame的每个元素上。


【例4-37】将水果价格表中的“元”去掉。
data = {'fruit': ['apple', 'grap', 'banana'], 'price': ['30元', '43元', '28元']}
df1 = pd.DataFrame(data)
print(df1)
def f(x):
    return x.split('元')[0]
df1['price'] = df1['price'].map(f)
print('修改后的数据表:\n', df1)

b399baa8312141ef89a127a48911ce2f.png


【例4-38】apply函数的使用方法。
df2 = pd.DataFrame(np.random.randn(3, 3), columns = ['a', 'b', 'c'], index = ['app', 'win', 'mac'])
print(df2)
df2.apply(np.mean)

image.png


【例4-39】applymap函数的用法
print(df2)
df2.applymap(lambda x:'%3f' % x)

400a1bb855a9440cb9b4cf536f018868.png


4.4.3 排序

sort_index方法:对索引进行排序,默认为升序,降序排序时加参数ascending=False。

sort_values方法:对数值进行排序。by参数设置待排序的列名


【例 4 - 40】Series 的排序
wy = pd.Series([1, -2, 4, -4], index = ['e', 'b', 'a', 'd'])
print(wy)
print('排完序后的:\n', wy.sort_index())

f74dba8bbeb74eb6b7e1f6e625381605.png


【例 4 - 41】 排序
print('值排序后的 Series:\n', wy.sort_values())

f6c09143921e412ca99cca9968bdccfa.png

对于DataFrame数据排序,通过指定轴方向,使用sort_index函数对行或列索引

进行排序。如果要进行列排序,则通过sort_values函数把列名传给by参数即可。


【例4-42】DataFrame排序。
print(df2)
df2.sort_values(by = 'a')

077154a1c5544dadbbaf0c081316f414.png


4.4.4 汇总与统计
1)数据汇总

在 DataFrame 中,可以通过 sum 方法对每列进行求和汇总,与 Excel 中的 sum函数类似。如果设置axis = 1指定轴方向,可以实现按行汇总。


【例 4 - 43】 DataFrame中的汇总
print('按列汇总:\n', df2.sum())
print('按行汇总:\n', df2.sum(axis = 1))

3cae935adbc740f5877a1b54f8bd69d4.png


2)数据描述与统计

利用describe方法会对每个数值型的列数据进行统计。

【例 4 - 44】describe示例
df2.describe()

da7d643b7d614faab40b942e4f9febb1.png


表4-3.Pandas中常用的描述性统计量

函数 使用说明
count 计数
sum 求和
mean 求平均值
median 求中位数
std、var 无偏标准差和方差
min、max 求最小值最大值
prod 求积
first、last 第一个和最后一个值

对于类别型特征的描述性统计,可以使用频数统计表。Pandas库中通过unique方法获取不重复的数组,利用value_counts方法实现频数统计


【例 4 - 45】 数据的频数统计
obj = pd.Series(['a', 'b', 'c', 'a', 'd', 'c'])
print(obj.unique())
print(obj.value_counts())

f8fc1ae645cd497d9dbe0304dde65909.png


4.5 数据分组与聚合

4.5.1 数据分组

Pandas提供了一个高效的groupby方法,配合agg或apply方法实现数据分组聚合的操作。


1)groupby方法

groupby方法可以根据索引或字段对数据进行分组。

格式为:

DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, **group_keys=True, squeeze=False, kwargs)


表4-4. groupby方法的参数及其说明

参数名称 参数说明
by 可以传入函数、字典、Series等,用于确定分组的依据
axis 接收int,表示操作的轴方向,默认为0
level 接收int或索引名,代表标签所在级别,默认为None
as_index 接收boolean,表示聚合后的标签是否以DataFrame索引输出
sort 接收boolean,表示对分组依据和分组标签排序,默认为True
group_keys 接收boolean,表示是否显示分组标签的名称,默认为True
squeeze 接收boolean,表示是否在允许情况下对返回数据降维,默认False


【例 4 - 46】groupby 基本用法
import pandas as py
import numpy as np
df = pd.DataFrame({'key1': ['a', 'a', 'b', 'b', 'a'],
                   'key2': ['yes', 'no', 'yes', 'yes', 'no'],
                   'data1': np.random.randn(5),
                   'data2': np.random.randn(5)})
grouped = df['data1'].groupby(df['key1'])
print(grouped.size())
print(grouped.mean())

2c78d69ad3294ea8a1abb7ab5886ffd7.png


2)按列名分组

DataFrame 数据的列索引名可以作为分组键,但需要注意的是用于分组的对象必须是DataFrame数据本身,否则搜索不到索引名称会报错。


【例 4 - 47】列索引名称作为分组键
groupk1 = df.groupby('key2').mean()
groupk1

40d6a20479a9409b95dc7985bf8996a3.png


3)按列表或元组分组

分组键还可以是长度和DataFrame行数相同的列表或元组,相当于将列表或元组看做DataFrame的一列,然后将其分组。


【例4-48】按列表或元组分组。
display(df)

6d4b545bef6d48aa9289ba4cf485e6ba.png


4)按字典分组

如果原始的DataFrame中的分组信息很难确定或不存在,可以通过字典结构,定义分组信息。

【例4-49】通过字典作为分组键,分组时各字母不区分大小写

df = pd.DataFrame(np.random.normal(size = (6,5)),index = ['a','b','c','A','B','c'])
print("数据为:\n",df)
wdict = {'a':'one','A':'one','b':'two','B':'two','c':'three'}
print("分组汇总后的结果为:\n",df.groupby(wdict).sum())

image.png


5)按函数分组

函数作为分组键的原理类似于字典,通过映射关系进行分组,但是函数更加灵活。


【例4-50】通过DataFrame最后一列的数值进行正负分组。
def judge(x):
    if x>=0:
        return 'a'
    else:
        return 'b'
df = pd.DataFrame(np.random.randn(4,4))
print(df)
print(df[3].groupby(df[3].map(judge)).sum())


52dfe92a031d4659b470c5d4b2739a2e.png


4.5.2 数据聚合
1)聚合函数

除了之前示例中的mean函数外,常用的聚合运算还有count和sum等


表4-5. 聚合运算方法

函数 使用说明
count 计数
sum 求和
mean 求平均值
median 求中位数
std、var 无偏标准差和方差
min、max 求最小值最大值
prod 求积
first、last 第一个和最后一个值


2)使用agg方法聚合数据

agg、aggregate方法都支持对每个分组应用某个函数,包括Python内置函数或自定义函数。同时,这两个方法也能够直接对DataFrame进行函数应用操作。在正常使用过程中,agg和aggregate函数对DataFrame对象操作的功能基本相同,因此只需掌握一个即可。

7e5917b2f5d84cf6a317b271010572b3.png


【例4-51】使用agg求出当前数据对应的统计量。
import pandas as pd
data = pd.read_excel('C:\\Users\\86152\\testdata.xls')
data.head()
data.info()
data[['淋巴细胞计数','白细胞计数']].agg([np.sum,np.mean])

00d734b0fddc47febdd5b9eb51039988.png


【例4-52】利用agg分别求字段的不同统计量。
data.agg({'淋巴细胞计数':np.mean,'血小板计数':np.std})

aaabb633bf304bf4914161ea225ba71a.png


3)计算不同字段的不同数目的统计量
【例4-53】不同字段统计不同数目的统计量。

data.agg({'淋巴细胞计数':np.mean,'血小板计数':[np.mean,np.std]})

f2c675fa0a6b4fa584ba31a5ebca9536.png


【例4-54】统计不同性别人群的血小板计数
data.groupby('性别')['血小板计数'].agg(np.mean)

2dd85915330a473485cc7552fc600361.png


【例4-55】as_index参数的用法。
data.groupby(['性别','是否吸烟'],as_index = False)['血小板计数'].agg(np.mean)

9712de5f111b4595bb55edbafd3c6034.png


4.5.3 分组运算
1)transform方法

通过transform方法可以将运算分布到每一行。

data.groupby(['性别','是否吸烟'])['血小板计数'].transform('mean').sample(5)


【例4-56】transform方法.png)]

75af203c46294dadbf3d49ded1b32675.png


2)使用apply方法聚合数据

apply方法类似于agg方法,能够将函数应用于每一列。

【例4-57】数据分组后应用apply统计。
data.groupby(['性别','是否吸烟'])['血小板计数'].apply(np.mean)

00d5c03052e041dfbba896e3e7137c4c.png


表4-5. pivot_table函数主要参数及其说明

参数 使用说明
data 接收DataFrame,表示创建表的数据
values 接收string,指定要聚合的数据字段,默认全部数据
index 接收string或list,表示行分组键
columns 接收string或list,表示列分组键
aggfunc 接收functions,表示聚合函数,默认为mean
margins 接收boolean,表示汇总功能的开关
dropna 接收boolean,表示是否删掉全为NaN的列,默认False


【例4-58】pivot_table默认计算均值。
import pandas as pd
import numpy as np
data = pd.DataFrame({'k1':['a','b','a','a','c','c','b','a','c','a','b','c'],'k2':['one',
'two','three','two','one','one','three','one','two','three','one','two'],
'w':np.random.rand(12),'y':np.random.randn(12)})
print(data)
print("------------------------------------------------")
print(data.pivot_table(index = 'k1',columns = 'k2'))

72794c5321b24116a9589bd7e8dfbd98.png


【例4-59】分类汇总并求和。
data.pivot_table(index = 'k1',columns = 'k2',aggfunc = 'sum')

ced7869fdf784caa8f14de12ab085b66.png


4.6.2 交叉表

交叉表是一种特殊的透视表,主要用于计算分组频率。

crosstab的格式:

crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False, dropna=True, normalize=False)


表4-6. crosstab主要参数及其说明

参数 使用说明
index 接收 string或list,表示行索引键,无默认
columns 接收string或list,表示列索引键
values 接收array,表示聚合数据,默认为None
rownames 表示行分组键名,无默认
colnames 表示列分组键名,无默认
aggfunc 接收functions,表示聚合函数,默认为None
margins 接收boolean,表示汇总功能的开关
dropna 接收boolean,表示是否删掉全为NaN的列,默认False
normalize 接收boolean,表示是否对值进行标准化,默认为False


【例4-60】交叉表示例。
pd.crosstab(data.k1,data.k2)

8b22976822de4b9c84622091d24ed5f2.png


【例4-61】带参数margin。
pd.crosstab(data.k1,data.k2,margins = True)

3c4b589dbcb84b49a92dc56b35fc5ce3.png


4.7 Pandas 可视化

Pandas中集成了Matplotlib中的基础组件,让绘图更加便捷。

表 4 - 8 Series.plot 的主要参数及其说明

1b52d4879445421bace8cefb98a6013a.png


表 4 - 9 DataFrame.plot 的主要参数及其说明

d8df37bc3cdd40ec841f24dd4de5a079.png

4.7.1 线行图

Pandas库中的Series和DataFrame中都有绘制各类图表的plot方法,默认绘制的都是线形图。通过DataFrame对象的plot方法可以为各列绘制一条线,并创建图例。


【例4-62】Series的plot方法绘图。
import matplotlib.pyplot as plt
%matplotlib inline
s = pd.Series(np.random.normal(size = 10))
s.plot()


【例4-63】DataFrame的plot方法绘图。
df = pd.DataFrame({'normal':np.random.normal(size = 50),'gamma':np.
random.gamma(1,size = 50)})
df.plot()

6d5d62b14f664a5181ebbd3b49a06002.png


4.7.2 柱状图

在Pandas中绘制柱状图只需在plot函数中加参数kind = ‘bar’,如果类别较多,可以绘制水平柱状图(kind = ‘barh’)。


【例4-64】DataFrame中绘制柱状图。
stu = {'name':['小明','王芳','赵平','李红','李涵'],
      'sex':['male','female','female','female','male'],
      'year':[1996,1997,1994,1999,1996]}
data = pd.DataFrame(stu)
print(data['sex'].value_counts())
print(data['sex'].value_counts().plot(kind = 'bar',rot = 30))

6d5d62b14f664a5181ebbd3b49a06002 (1).png


4.7.2 柱状图

在Pandas中绘制柱状图只需在plot函数中加参数kind = ‘bar’,如果类别较多,可以绘制水平柱状图(kind = ‘barh’)。


【例4-64】DataFrame中绘制柱状图。
stu = {'name':['小明','王芳','赵平','李红','李涵'],
      'sex':['male','female','female','female','male'],
      'year':[1996,1997,1994,1999,1996]}
data = pd.DataFrame(stu)
print(data['sex'].value_counts())
print(data['sex'].value_counts().plot(kind = 'bar',rot = 30))

image.png



【例4-65】DataFrame数据对象的柱状图。

df = pd.DataFrame(np.random.randint(1,100,size = (3,3)),index = 
{'one','two','three'},columns = ['I1','I2','I3'])
df.plot(kind = 'barh')

5fee9e05deed477f8357d0ec16a89f56.png


4.7.3 直方图和密度图

直方图用于频率分布,y轴为数值或比率。绘制直方图,可以观察数据值的大致分布规律。pandas中的直方图可以通过hist方法绘制。核密度估计是对真实密度的估计,其过程是将数据的分布近似为一组核(如正态分布)。通过plot函数的kind = ‘kde’可以进行绘制。


【例4-66】pandas中直方图绘制。
wy = pd.Series(np.random.normal(size = 80))
s.hist(bins = 15,grid = False)

image.png

直方图用于频率分布, y 轴为数值或比率。绘制直方图,可以观察数据值的大致分布规律。pandas中的直方图可以通过hist方法绘制。

核密度估计是对真实密度的估计,其过程是将数据的分布近似为一组核(如正态分布)。通过plot函数的kind = ‘kde’可以进行绘制。


【例4-67】panas中密度图的绘制。
wy = pd.Series(np.random.normal(size = 80))
s.plot(kind = 'kde')

bafc16bcba414eec956893c123568e87.png


4.7.4 散点图

散点图主要用来表现数据之间的规律。通过plot函数的kind = 'scatter’可以进行绘制。


【例4-68】pandas绘制散点图。
wd = pd.DataFrame(np.arange(10),columns = ['A'])
wd['B'] = 2*wd['A']+4
wd.plot(kind = 'scatter',x = 'A',y = 'B')

7d493345cfb6456c80e7a532a6cd7e38.png


(1)导入模块
import numpy as np
import pandas as pd
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
%matplotlib inline


(2)获取数据

导入待处理的数据 tips.xls,并显示前 5 行

fdata=pd.read_excel('C:\\Users\\86152\\tips.xls')
fdata

image.png


(3)查看数据
1)查看数据的描述信息
fdata.describe()


ff69d918b17b48d7b9028b0d5c23daed.png


2)修改列名为汉字,并显示前 5 行数据

e6b9fdfa0cfc45fdb1df0a4b711dabef.png


3)人居消费
fdata['人均消费']=round(fdata['消费总额']/fdata['人数'],2)
fdata.head()

81b12f2b3c1d485b8823554383ec245b.png


4)查询抽烟男性中人均消费大于 15 的数据

# 方法1:
fdata[(fdata['是否抽烟']=='Yes') &(fdata['性别']=='Male') & (fdata['人均消费']> 15) ]
# 方法2:
# fdata[(fdata.是否抽烟=='Yes') &(fdata.性别=='Male') & (fdata.人均消费> 15) ]
# 方法3:
# fdata.query( '是否抽烟=="Yes" & 性别=="Male" & 人均消费>15')

image.png


5)分析小费和总金额的关系,散点图

#分析小费和总金额的关系,散点图
fdata.plot(kind='scatter',x='消费总额',y='小费')
#正相关关系

f61ec2257e244910a3ebe00d72a9d7cc.png


· 6)分析男女顾客哪个更慷慨,就是分组看看男性还是女性的小费平均水平更高
#分析男女顾客哪个更慷慨,就是分组看看男性还是女性的小费平均水平更高
fdata.groupby('性别')['小费'].mean()

1285c0908ead491baa59dbc15ac708e6.png


7)分析日期和小费的关系
#分析日期和小费的关系,直方图
print(fdata['星期'].unique())
r=fdata.groupby('星期')['小费'].mean()
fig=r.plot(kind='bar',x='星期',y='小费',fontsize=12,rot=36)
# fig.axes.title.set_size(16)

0e67e72e015e4d23b5f1133f6cff9fb4.png


8)性别+抽烟书对慷慨度的影响

#性别+抽烟书对慷慨度的影响
r=fdata.groupby(['性别','是否抽烟'])['小费'].mean()
fig=r.plot(kind='bar',x=['性别','是否抽烟'],y='小费',fontsize=12,rot=30)
fig.axes.title.set_size(16)

7605e23fc33041bdaa52c87a7ba2157e.png


9)聚餐时间与小费数额的关系
#聚餐时间与小费数额的关系
r=fdata.groupby('聚餐时间段')['小费'].mean()
fig=r.plot(kind='bar',x='聚餐时间',y='小费')
fig.axes.title.set_size(16)

4cd647c81caf4fc0a4130478dece4aca.png









目录
相关文章
|
SQL 分布式计算 数据挖掘
PySpark数据分析基础:PySpark Pandas创建、转换、查询、转置、排序操作详解
PySpark数据分析基础:PySpark Pandas创建、转换、查询、转置、排序操作详解
528 0
PySpark数据分析基础:PySpark Pandas创建、转换、查询、转置、排序操作详解
|
2月前
|
数据可视化 数据挖掘 Linux
第四章 Pandas 统计分析基础
第四章 Pandas 统计分析基础
56 0
|
资源调度 BI 项目管理
第一章 pandas预备知识(列表推导式与条件赋值、匿名函数与map方法、zip对象与enumerate方法、np基础 )
第一章 pandas预备知识(列表推导式与条件赋值、匿名函数与map方法、zip对象与enumerate方法、np基础 )
119 0
|
数据挖掘 数据处理 Python
python数据分析-pandas基础(4)-数据映射apply
apply函数的作用:就是用某个指定的函数f来依次作用于DataFrame或者Series的每个数据,可以指定按行处理和按列处理。
267 0
|
数据库 开发者 索引
Pandas 基础3|学习笔记
快速学习 Pandas 基础3
71 0
Pandas 基础3|学习笔记
|
开发者 索引 Python
Pandas 基础5|学习笔记
快速学习 Pandas 基础5
78 0
|
开发者 索引 Python
Pandas 基础4|学习笔记
快速学习 Pandas 基础4
126 0
|
开发者 索引 Python
Pandas 基础2|学习笔记
快速学习 Pandas 基础2
64 0
|
开发者 索引 Python
Pandas基础 6|学习笔记
快速学习 Pandas基础 6
46 0
|
开发者 数据库管理 索引
Pandas 基础 1|学习笔记
快速学习 Pandas 基础 1
122 0