1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 数据分析与可视化(四)Pandas学习基础一:统计分析基础

数据分析与可视化(四)Pandas学习基础一:统计分析基础

时间:2024-05-05 08:41:38

相关推荐

数据分析与可视化(四)Pandas学习基础一:统计分析基础

文章目录

1. pandas的数据结构series:一维数组对象,通过索引来访问DataFrame:有一组有序的列,表格型的数据结构索引对象查看DataFrame的常用属性2.Pandas的索引操作重建索引1.重建索引3.reindex操作更换索引3.DataFrame数据的查询和编辑查询【一般都是通过索引来操作的】1.选取列2.选取行3.读取行和列4.布尔选择编辑【提取需要编辑的数据,重新赋值】1.增加数据2.删除数据3.修改数据4.pandas数据运算算术运算函数的应用和映射排序统计汇总5.数据分组与聚合数据分组数据聚合:对分组后的数据进行计算,产生标量值的数据转换过程。分组运算:包含聚合运算,聚合运算是数据转换的特例。重要技巧: `groupby`之后直接`.reset_index()`可以得到一个没有多级索引的DataFram,之后可以通过`df.rename({‘old_col1’:‘new_col1’,‘old_col2’:‘new_col2’,…})`重命名6.数据透视表透视表交叉表:是一种特殊的透视表,主要用于计算分组频率。使用Pandas提供的crosstab函数可以制作。7.Pandas可视化线形图柱状图直方图和密度图散点图

1. pandas的数据结构

Series:类似于数组DataFrame:类似于表格Panel:Excel多表单Sheet【不常用】

series:一维数组对象,通过索引来访问

1.创建:可通过列表和字典来创建

import pandas as pdimport numpy as nps1 = pd.Series([1,4,'ab',0])s2 = pd.Series({'A':'111', 'B':'你好', 'C':'345'})print(s1,'\t',s2)#>>>>>>>输出结果:01142 ab30dtype: object A 111B你好C 345dtype: object

2.索引

(1)列表建立Series对象时,没有指定index,会自己生成整数型索引,可用使用索引切片技术;指定index时,Series会有两种描述某数据的手段,自己生成的整数位置索引和建立Series对象时给定的index索引(标签);dtype用来给定数据类型。

import pandas as pdlist1 = [1,3,5,7]s1 = pd.Series(list1, index=['a1', 'b1', 'c1', 'd1'], dtype='object')print('s1 index索引取值',s1['a1'])print('s1 位置取值',s1[0])#>>>>>>>结果:s1 index索引取值 1s1 位置取值 1

(2)字典建立Series对象时,不指定index,默认会用字典键有序排列来做索引;指定index时,如果键值与指定的index不匹配,会生成NaN(非数字);给定的index索引可用通过赋值方式修改

import pandas as pddic = {'a':'中国','b':'日本','d':'美国'}s = pd.Series(dic, index=['a', 'b', 'c', 'd'])print(s)s.index = ['A', 'B', 'C','D']#>>>>>>>结果:a中国b日本c NaNd美国dtype: object修改index: A中国B日本C NaND美国dtype: object

DataFrame:有一组有序的列,表格型的数据结构

1.创建:最常用的是直接传入一个由等长列表或者NumPy数组组成的字典来形成DataFrame。

2.特性:会自动加上索引,且全部列会被有序排列,如果columns指定列名序列,则按指定列名排列;index给出行标签;如果传入的列在数据中找不到,会产生NaN值。

data = {'name':['张飞', '孙尚香', '韩信', '貂蝉', '马超'],'location':['游走', '下路', '打野', '中单', '上单'],'dynasty':['蜀', '蜀', '战国', '汉', '蜀'],'year':[1999, 2000, , 2050, 3030]}df = pd.DataFrame(data)print(df)#>>>>>>结果:name location dynasty year0 张飞 游走 蜀 19991 孙尚香 下路 蜀 20002 韩信 打野战国 3 貂蝉 中单 汉 20504 马超 上单 蜀 3030

df = pd.DataFrame(data, columns=['name','location','dynasty','address','year'],index=['a','b','c','d','e'])print(df)#>>>>>>>>结果:name location dynasty address yeara 张飞 游走 蜀NaN 1999b 孙尚香 下路 蜀NaN 2000c 韩信 打野战国NaN d 貂蝉 中单 汉NaN 2050e 马超 上单 蜀NaN 3030

索引对象

1.pandas的索引对象负责管理轴标签和其它元数据信息(例如轴名称等),构建Series和DataFrame时,所用到的任何数组或其它序列的标签,都会被转换成一个Index。

print(df.index)print(df.columns)#>>>>>>>结果:Index(['a', 'b', 'c', 'd', 'e'], dtype='object')Index(['name', 'location', 'dynasty', 'address', 'year'], dtype='object')

2.Index长的像数组,功能类似于一个固定大小的集合。不可修改保证Index在多个数据结构间的安全共享。

print('name' in df.columns)df.index=['1','2','3','4','5']df.columns=['a','b','c','d','e']print(df)#>>>>>>>结果:Truea b c de1 张飞 游走 蜀 NaN 19992 孙尚香 下路 蜀 NaN 20003 韩信 打野 战国 NaN 4 貂蝉 中单 汉 NaN 20505 马超 上单 蜀 NaN 3030

3.索引的方法和属性

df.index.insert(1,'w')#>>>>>>>结果:Index(['1', 'w', '2', '3', '4', '5'], dtype='object')

查看DataFrame的常用属性

print(df)print("--------------")print(df.values())print("--------------")print(df.index())print("--------------")print(df.columns())print("--------------")print(df.dtypes())print("--------------")print(df.ndim())print("--------------")print(df.shape())print("--------------")print(df.size())#>>>>>>>结果:a b c de1 张飞 游走 蜀 NaN 19992 孙尚香 下路 蜀 NaN 20003 韩信 打野 战国 NaN 4 貂蝉 中单 汉 NaN 20505 马超 上单 蜀 NaN 3030--------------[['张飞' '游走' '蜀' nan 1999]['孙尚香' '下路' '蜀' nan 2000]['韩信' '打野' '战国' nan ]['貂蝉' '中单' '汉' nan 2050]['马超' '上单' '蜀' nan 3030]]--------------Index(['1', '2', '3', '4', '5'], dtype='object')--------------Index(['a', 'b', 'c', 'd', 'e'], dtype='object')--------------a objectb objectc objectd objecteint64dtype: object--------------2--------------(5, 5)--------------25

2.Pandas的索引操作

索引对象是无法修改的,因此重建索引是指对索引的重新排序而不是重新命名,如果某个索引值不存在的话会引入缺失值。

重建索引
1.重建索引

import pandas as pdimport numpy as npobj = pd.Series([3,4.5,9,0], index = ['a','c','b','d'])print(obj)obj.reindex(['a','b','c','d','e'])》》》》》》结果:a 3.0c 4.5b 9.0d 0.0dtype: float64a 3.0b 9.0c 4.5d 0.0e NaNdtype: float64###### 2.填充重建索引时引入的缺失值【前向与后向填充】```python#填充缺失值obj.reindex(['a','c','c','d','e'], fill_value=10)》》》》》》结果:a3.0c4.5c4.5d0.0e 10.0dtype: float64

#前向填充和后向填充:method='ffill\bfill'obj1 = pd.Series(['blue','red','black'], index = [0,2,4])obj1.reindex(np.arange(6), method = 'ffill')>>>>>结果:0blue1blue2red3red4 black5 blackdtype: objectobj2 = pd.Series(['blue','red','black'], index = [0,2,4])obj2.reindex(np.arange(6), method = 'bfill')>>>>>结果:0blue1red2red3 black4 black5NaNdtype: object

3.reindex操作

对于DataFrame,reindex可以修改(行)索引、列,或两个都修改。如果只传入一个序列,则结果中的行会重建索引。

更换索引

在DataFrame数据中,如果不想用默认的行索引,则可以在创建时通过Index参数来设置。有时希望将列数据作为索引,可以用set_index方法来实现。与set_index相反的是reset_index。

data = {'name':['张飞', '孙尚香', '韩信', '貂蝉', '马超'],'location':['游走', '下路', '打野', '中单', '上单'],'dynasty':['蜀', '蜀', '战国', '汉', '蜀'],'year':[1999, 2000, , 2050, 3030]}df = pd.DataFrame(data, columns=['name','location','dynasty','address','year'],index=['a','b','c','d','e'])df1 = df.set_index('dynasty')print(df1)name location address yeardynasty 蜀 张飞 游走NaN 1999蜀 孙尚香 下路NaN 2000战国 韩信 打野NaN 汉 貂蝉 中单NaN 2050蜀 马超 上单NaN 3030

3.DataFrame数据的查询和编辑

查询【一般都是通过索引来操作的】
1.选取列

通过列索引标签或者属性的方式可以单独获取DataFrame的列数据,返回数据类型为Series。在选取列时不能使用切片的方式,超过一个列名用df[['列名1','列名2']]

#选取列import pandas as pdimport numpy as npdata = {'name':['张三','李四','王麻子'],'age':[21,19,23],'address':['兰州','上海','北京']}df = pd.DataFrame(data)print(df)w1 = df['name']print("以列名取一列数据:\n", w1)w2 = df[['name','age']]print("以列名取两份数据:\n", w2)name age address0 张三 21兰州1 李四 19上海2 王麻子 23北京以列名取一列数据:0张三1李四2 王麻子Name: name, dtype: object以列名取两份数据:name age0 张三 211 李四 192 王麻子 23

2.选取行

通过行索引或者行索引位置切片形式获取行数据【从0开始的,左闭右开】。DataFrame提供的head【开头开始】和tail【结尾】可以取连续多行数据,sample可以随机抽取并显示数据

#取行 从0开始的print('显示前两行:\n', df[:2])print('显示2行:\n', df[1:2])#head从第一行取,默认前五行print(df.head())print(df.head(1))#tail默认最后五行 可以带数字取最后的print(df.tail())print(df.tail(1))#sample随机抽取n行显示print(df.sample(2))显示前两行:name age address0 张三 21兰州1 李四 19上海显示2行:name age address1 李四 19上海name age address0 张三 21兰州1 李四 19上海2 王麻子 23北京name age address0 张三 21兰州name age address0 张三 21兰州1 李四 19上海2 王麻子 23北京name age address2 王麻子 23北京name age address2 王麻子 23北京1 李四 19上海

3.读取行和列

切片选取行限制比较大,取单独的几行数据可以采用Pandas提供的iloc和loc方法实现。

用法:DataFrame.loc(行索引位置, 列索引位置)

​ DataFrame.loc(行索引名称或条件, 列索引名称)

#locdata = {'name':['张飞', '孙尚香', '韩信', '貂蝉', '马超'],'location':['游走', '下路', '打野', '中单', '上单'],'dynasty':['蜀', '蜀', '战国', '汉', '蜀'],'year':[1999, 2000, , 2050, 3030]}df1 = pd.DataFrame(data, columns=['name','location','dynasty','address','year'],index=['a','b','c','d','e'])df2 = df1.set_index('dynasty')print(df2)print("取name和year两列的数据:\n",df2.loc[:,['name','year']])print("取汉,战国行中name,year的数据:\n",df2.loc[['汉','战国'],['name','year']])name location address yeardynasty 蜀 张飞 游走NaN 1999蜀 孙尚香 下路NaN 2000战国 韩信 打野NaN 汉 貂蝉 中单NaN 2050蜀 马超 上单NaN 3030取name和year两列的数据:name yeardynasty 蜀 张飞 1999蜀 孙尚香 2000战国 韩信 汉 貂蝉 2050蜀 马超 3030取汉,战国行中name,year的数据:name yeardynasty 汉 貂蝉 2050战国 韩信

#iloc [索引0开始]print("显示前两列:\n", df2.iloc[:, 2])print("显示第1和第3行的第2列:\n", df2.iloc[[1,3],[0]])显示前两列:dynasty蜀1999蜀2000战国 汉2050蜀3030Name: year, dtype: int64显示第1和第3行的第二列:namedynasty蜀 孙尚香汉 貂蝉

也可以使用ix方法实现行和列的选择,同时支持索引标签和索引位置取值。

4.布尔选择

用选择符不等于(!=)、与(&)、或(|)

df3 = df2[df2['year'] == 3030]print(df3,type(df3))#返回dataframe型df2['name']=='孙尚香'#返回布尔类型name location yeardynasty蜀 马超 上单 3030 <class 'pandas.core.frame.DataFrame'>dynasty蜀False蜀True战国 False汉False蜀FalseName: name, dtype: bool

编辑【提取需要编辑的数据,重新赋值】
1.增加数据

增加一行通过append方法传入字典结构数据即可,增加列时为增加的列赋值即可创建一个新的列,具体给值要对应,不然会报错

#插入一行数据append#加列并赋值df1['C'] = 10df1['age'] = [24,33,19,40,80]data1 = {'name':'李白','location':'打野','dynasty':'唐','year':'1909'}df1.append(data1,ignore_index=True)name location dynasty year C age0 张飞 游走 蜀 1999 10 241 孙尚香 下路 蜀 2000 10 332 韩信 打野战国 10 193 貂蝉 中单 汉 2050 10 404 马超 上单 蜀 3030 10 80namelocationdynastyyearCage0张飞游走蜀199910.024.01孙尚香下路蜀200010.033.02韩信打野战国20.019.03貂蝉中单汉205010.040.04马超上单蜀303010.080.05李白打野唐1909NaN

2.删除数据

删除数据直接用drop方法,行列数据通过axis参数设置默认为0删除行,1删除列。默认数据删除不修改原数据,如果在原数据上删除加入参数inplace=True即可。

#删除数据的行和列 没有指定inplace=True,删除不是在原数据上操作的df1.drop('C',axis=1)print(df1)name location dynasty year C age0 张飞 游走 蜀 1999 10 241 孙尚香 下路 蜀 2000 10 332 韩信 打野战国 10 193 貂蝉 中单 汉 2050 10 404 马超 上单 蜀 3030 10 80df1.drop('C',axis=1,inplace=True)print(df1)name location dynasty year age0 张飞 游走 蜀 1999 241 孙尚香 下路 蜀 2000 332 韩信 打野战国 193 貂蝉 中单 汉 2050 404 马超 上单 蜀 3030 80

3.修改数据

对选择的数据进行赋值就可以了。**修改数据是对DataFrame值的修改,无法撤销。**如新列赋值。

4.pandas数据运算

算术运算

如果有相同索引则进行算术运算,如果没有则会进行数据对齐,但会引入缺失值。对于DataFrame类型,数据对齐的操作会同时发生在行和列上。

import pandas as pdimport numpy as np##Series相加obj1 = pd.Series([1,4,-1,9,0,-8], index=['a','b','d','e','f','g'])obj2 = pd.Series([4,9,0,-4,-1,10], index=['a','c','d','e','f','h'])print("obj1:\n",obj1)print("obj2:\n",obj2)print(obj1+obj2)obj1:a 1b 4d -1e 9f 0g -8dtype: int64obj2:a4c9d0e -4f -1h 10dtype: int64a 5.0b NaNc NaNd -1.0e 5.0f -1.0g NaNh NaNdtype: float64

## DataFrame 行和列均会对齐给NaN值import pandas as pdimport numpy as npdf1 = pd.DataFrame(np.arange(12).reshape(3,4), columns=['a','b','c','d'], index=['A','B','C'])df2 = pd.DataFrame(np.arange(9).reshape(3,3), columns=['a','c','d'], index=['A','B','D'])print("df1:\n",df1)print("df1:\n",df2)print(df1+df2)df1:a b c dA 0 1 2 3B 4 5 6 7C 8 9 10 11df1:a c dA 0 1 2B 3 4 5D 6 7 8a bcdA 0.0 NaN 3.0 5.0B 7.0 NaN 10.0 12.0C NaN NaN NaN NaND NaN NaN NaN NaN

函数的应用和映射

1.定义函数进行较为复杂的数据处理过程

(1).map函数:将函数套入到Series的每个元素中

(2).apply函数:将函数套用到DataFrame的行和列上,行和列通过axis参数指定。

(3).applymap函数:将函数套用到DataFrame的每个元素上。

匿名函数:lambda 参数列表 : 关于参数的表达式e.g:lambda x,y:x+y:该函数的输入是x和y,输出是x+y的值

#去掉水果价格中的 元 字data = {'fruit':['apple','grape','banana'],'price':['30元','40元','50元']}df = pd.DataFrame(data)print(df)def f1(x):return x.split('元')[0]#按’元‘分割 取第一个位置的df['price'] = df['price'].map(f1)#map函数会循环给所给数据的每一个元素执行f1函数print(df)fruit price0 apple 30元1 grape 40元2 banana 50元fruit price0 apple 301 grape 402 banana 50

##apply函数 套用到df的行与列 axis[轴] axis=1 按行运算df = pd.DataFrame(np.random.randn(3,3), columns=['a','b','c'], index=['app','win','mic'])print(df)df.apply(np.mean,axis=1)a b capp -0.336255 -0.446342 -0.888068win 2.742748 2.432790 -1.444682mic 0.567298 -0.268666 0.039183app -0.556888win 1.243619mic 0.112605dtype: float64

##applymap 套用到df每个元素 对整个df进行批量处理#匿名函数:lambda 参数列表 : 关于参数列表的表达式(一行)【输入是传递进来的参数列表的值,输出是根据表达式计算所得的值】print(df)df.applymap(lambda x:'%.3f'%x)a b capp -0.336255 -0.446342 -0.888068win 2.742748 2.432790 -1.444682mic 0.567298 -0.268666 0.039183abcapp-0.336-0.446-0.888win2.7432.433-1.445mic0.567-0.2690.039

排序

在Series中,通过sort_index方法对索引进行排序,通过sort_values对数值进行排序,默认升序,降序加参数ascending=False

##排序 Series dataframe sort_index([ascending=False]) 默认升序,False降序 sort_values([by='列名'])obj = pd.Series([-1,0,-9,9,5],index=['a','c','b','e','d'])print('值排序:\n',obj.sort_values())print('索引降序:\n',obj.sort_index(ascending=False))值排序:b -9a -1c 0d 5e 9dtype: int64索引降序:e 9d 5c 0b -9a -1dtype: int64

对于DataFrame的排序,通过指定axis轴的方向,使用sort_index对行或列索引进行排序,若要进行列排序,用sort_values(by='列名')

#DataFrameprint(df)print(df.sort_values(by='a'))a b capp -0.336255 -0.446342 -0.888068win 2.742748 2.432790 -1.444682mic 0.567298 -0.268666 0.039183a b capp -0.336255 -0.446342 -0.888068mic 0.567298 -0.268666 0.039183win 2.742748 2.432790 -1.444682

统计汇总

1.数据汇总:sum函数可以对每列求和汇总。axis=1可以实现按行汇总

##数据汇总 axis=1是按行 默认按列print(df)print('按列汇总:\n',df.sum())print('按行汇总:\n',df.sum(axis=1))a b capp -0.336255 -0.446342 -0.888068win 2.742748 2.432790 -1.444682mic 0.567298 -0.268666 0.039183按列汇总:a 2.973791b 1.717783c -2.293567dtype: float64按行汇总:app -1.670665win 3.730856mic 0.337815dtype: float64

2.数据的描述与统计

描述性统计表:

对于类别型特征的描述性统计,可以使用频数统计表。unique获取不重复的值。value_counts实现频数统计。

#数据的描述与统计obj = pd.Series([1,2,3,0,5,6,0,0,3])print('去重:\n',obj.unique())print('频数统计:\n',obj.value_counts())去重:[1 2 3 0 5 6]频数统计:0 33 21 12 15 16 1dtype: int64

5.数据分组与聚合

数据分组

1.groupby方法:DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False)

参数by,如果传入函数,则对索引进行计算并分组;如果传入字典或者Series,则字典或者Series的值作为分组依据;如果传入Numpy数组,则数据元素作为分组依据;如果传入字符串或者字符串列表,则用这些字符串所代表的字段作为分组依据。

数据分组之后返回的是一个groupby对象,可以调用该对象的方法如size返回一个含有分组大小的Series。

#取df['data1']这一列数据并按df['key1']这一列的数据来分组 分完之后a:3 ,b:2import numpy as npimport pandas as pd##groupby()df = pd.DataFrame({'key1':['a','a','b','b','a'],'key2':[1,0,1,1,0],'data1':np.random.randn(5),'data2':np.random.randn(5)})print(df)grouped = df['data1'].groupby(df['key1'])print(grouped.size())print(grouped.mean())key1 key2data1data20 a1 0.410518 0.2046811 a0 -0.558132 -0.0085012 b1 -0.008334 -1.9356303 b1 -0.481743 0.7751964 a0 0.597605 0.561882key1a 3b 2Name: data1, dtype: int64key1a 0.149997b -0.245038Name: data1, dtype: float64

2.按列名分组:DataFrame数据的列索引名可以作为分组键,但是用于分组的对象必须是DataFrame本身。不然会报错找不到索引名称。

#按列索引名称分组grouped1 = df.groupby('key1').size()grouped2 = df.groupby('key1').mean()print(grouped1)grouped2key1a 3b 2dtype: int64key2data1data2key1a0.3333330.1499970.252688b1.000000-0.245038-0.580217

3.按列表或元组分组:分组键还可以是和DataFrame行数相等的列表或者元组,相当于把列表或者元组当成DataFrame的一列,然后分组。

##所给的按列表或元组w = ['w','w','y','w','y']df.groupby(w).sum()key2data1data2w2-0.6293560.971377y10.589272-1.373748

4.按字典分组:如果原始的DataFrame中分组信息难以确定或不存在,则可以通过字典结构定义一个分组信息。

#定义一个字典来分组 分组信息:不区分大小写来分组df = pd.DataFrame(np.random.normal(size=(6,5)), index=['a','b','A','B','c','C'])print(df)dic = {"a":'one',"b":'two',"c":'three',"A":'one',"B":'two',"C":'three'}x = df.groupby(dic)print(x.sum())0 1 2 3 4a -0.422562 1.962075 -0.489384 -1.304302 -1.109478b 1.134703 -0.358548 -1.373025 0.851012 -0.302279A -0.196233 -0.192463 0.286070 0.872550 -0.835654B -0.038677 -0.130829 -0.599642 -0.65 -1.849057c -0.033203 -0.512046 -0.414564 0.516591 1.191699C -1.145768 0.176744 -0.160164 1.435075 -0.1248900 1 2 3 4one -0.618795 1.769613 -0.203314 -0.431753 -1.945131three -1.178971 -0.335301 -0.574728 1.951666 1.066808two 1.096026 -0.489377 -1.972667 0.649148 -2.151336

5.按函数分组:类似于字典,通过映射关系来进行分组

#函数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())0 1 2 30 0.714710 -1.180971 0.177371 1.2575261 -0.465390 0.822470 1.767948 0.7408392 0.194928 0.658354 -0.053870 -0.6578923 1.001120 -1.195080 1.122340 -1.813876a 1.998365b -2.471768Name: 3, dtype: float64

数据聚合:对分组后的数据进行计算,产生标量值的数据转换过程。

1.聚合函数:在聚合运算中,空值不参加计算

2.agg方法实现聚合数据:支持对每个分组应用某个函数。能直接对DataFrame进行函数应用操作。

#agg## 使用agg求出当前数据对应的统计量data = pd.read_excel('D:\python\数据分析与可视化\第四章:pandas统计分析基础\data\\testdata.xls')print(data.head())print('求当前数据的各项统计量:\n',data[['淋巴细胞计数','白细胞计数']].agg([np.sum, np.mean]))## 使用agg函数分别求各字段不同的统计量print('求个字段的不同统计量:\n',data.agg({'淋巴细胞计数':np.mean, '白细胞计数':np.std}))## 计算不同字段不同数目的统计量print('计算不同字段不同数目的统计量:\n',data.agg({'淋巴细胞计数':np.mean, '白细胞计数':[np.std, np.mean]}))## 统计不同性别人群的血小板计数的平均值print('统计不同性别人群的血小板计数:\n',data.groupby('性别')['血小板计数'].agg(np.mean))## 返回的数据不希望以分组键为索引 as_index=False实现print('统计不同性别人群的血小板计数:\n',data.groupby('性别',as_index=False)['血小板计数'].agg(np.mean))序号 性别 身份证号 是否吸烟 是否饮酒 开始从事某工作年份 体检年份 淋巴细胞计数 白细胞计数 细胞其它值 \0 1 女 ****1982080000 否 否 2.4 8.5 NaN 1 2 女 ****1984110000 否 否 1.8 5.8 NaN 2 3 男 ****1983060000 否 否 2.0 5.6 NaN 3 4 男 ****1985040000 否 否 2.5 6.6 NaN 4 5 男 ****1986040000 否 否 1.3 5.2 NaN 血小板计数 0 248.0 1 300.0 2 195.0 3 252.0 4 169.0 求当前数据的各项统计量:淋巴细胞计数 白细胞计数sum 4280.270000 6868.008100mean3.8491646.176266求个字段的不同统计量:淋巴细胞计数3.849164白细胞计数12.043418dtype: float64计算不同字段不同数目的统计量:淋巴细胞计数白细胞计数mean 3.849164 6.176266std NaN 12.043418统计不同性别人群的血小板计数:性别女 212.687636男 194.727417Name: 血小板计数, dtype: float64统计不同性别人群的血小板计数:性别 血小板计数0 女 212.6876361 男 194.727417

分组运算:包含聚合运算,聚合运算是数据转换的特例。

1.transform方法:将运算分不到每一行

# 分组运算## transform 运算分布到每一行data.groupby('性别')['血小板计数'].transform('mean').sample(5)915194.7274171039 194.7274171062 194.72741795194.727417416212.687636Name: 血小板计数, dtype: float64

2.apply方法:类似于agg方法,可以将函数应用于每一列

## apply 函数应用到每列 axis=1 应用到每行data.groupby(['性别','是否吸烟'])['血小板计数'].apply(np.mean)性别 是否吸烟女 否 212.133188是 297.333333男 否 194.236749是 195.210175

重要技巧:groupby之后直接.reset_index()可以得到一个没有多级索引的DataFram,之后可以通过df.rename({‘old_col1’:‘new_col1’,‘old_col2’:‘new_col2’,…})重命名

df1= df.groupby([‘date’])[‘price’].agg({‘sum’,‘count’}).reset_index()

6.数据透视表

数据透视表(Pivot Table)是数据分析中常见的工具之一,根据一个或多个键值对对数据进行聚合,根据列或行的分组键将数据划分到各个区域。

透视表

groupby()、pivot_table():均可以实现透视功能。

pivot_table(data, values=None, index=Nane, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')

import numpy as npimport pandas as pddata = pd.DataFrame({'k1':['a','b','c','a','c','d','e','b','d','c','a','c'],'k2':['one','two','three','one','two','three','three','three','one','two','one','two'],'w':np.random.rand(12),'y':np.random.randn(12)})print(data)data.pivot_table(index='k1',columns='k2')k1k2 w y0 a one 0.505038 -0.6926911 b two 0.760838 -1.1473332 c three 0.279918 -0.5110963 a one 0.361962 0.6057464 c two 0.605619 0.2172535 d three 0.708927 1.6326096 e three 0.760684 -0.0991347 b three 0.678767 0.8147718 d one 0.062156 -1.2476139 c two 0.800672 3.00844110 a one 0.958991 -0.01431111 c two 0.943706 0.486200wyk2onethreetwoonethreetwok1a0.608664NaNNaN-0.033752NaNNaNbNaN0.6787670.760838NaN0.814771-1.147333cNaN0.2799180.783332NaN-0.5110961.237298d0.0621560.708927NaN-1.2476131.632609NaNeNaN0.760684NaNNaN-0.099134NaN

由于复制过不来表格就截屏了 前面遇到过好几次透视表了,groupby出来的都是透视表。

分类汇总求和

交叉表:是一种特殊的透视表,主要用于计算分组频率。使用Pandas提供的crosstab函数可以制作。

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

##交叉表pd.crosstab(data.k1,data.k2,margins=True)#在边框处增加汇总k2onethreetwoAllk1a3003b0112c0134d1102e0101All44412

7.Pandas可视化

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

线形图

线形图一般用于描述两组数据之间的趋势。Pandas库中的Series和DataFrame中都有绘制各类图表的plot方法,默认绘制线形图。

import numpy as npimport pandas as pdimport matplotlib.pyplot as plt%matplotlib inline#线形图Seriesobj = pd.Series(np.random.normal(size=10))obj.plot()

# DataFramedf = pd.DataFrame({'normal':np.random.normal(size=50),'gamma':np.random.gamma(1, size=50)})df.plot()

柱状图

柱状图一般用来描述各类别之间的关系。在plot函数中加入参数kind='bar',如果类别较多,可以绘制水平柱状图(kind='barh')。

在DataFrame中绘制柱状图,对于DataFrame数据而言,每一行的值会成为一组。

# 柱状图 kind='bar'/'barh' 类别多少 rot:标签角度stu = {'name':['孙尚香','李白','韩信','马克','妲己'],'sex':['female','male','male','male','female'],'age':[19,20,22,21,25]}df = pd.DataFrame(stu)print(df['sex'].value_counts())print(df['sex'].value_counts().plot(kind='bar' ,rot=30))

DataFrame数据对象的柱状图:观察图很显然那个图和数据直接是有很明显的对应关系的,一行是一组图。

# 直接DataFrame作图 类别多 水平柱状图df = pd.DataFrame(np.random.randint(1,100, size=(4,4)), index=['a','b','c','d'], columns=['I1','I2','I3','I4'])df.plot(kind='barh')

直方图和密度图

直方图用于频率分布,Y轴为数值或者比率。绘制直方图可以先大致观察数据的大致分布规律。Pandas中的直方图有由hist方法绘制。

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

# 直方图【hist bins参数是y轴的值 grid是否有表格】obj1 = pd.Series(np.random.normal(size=80))obj1.hist(bins=15, grid=False)

#密度图【kind='kde'】obj1.plot(kind='kde')

散点图

散点图主要用来表示数据之间的规律,plot(kind='scatter')

#kind = 'scatter' 不能是Sreries 还得给定x与ydf1 = pd.DataFrame(np.arange(10), columns=['A'])df1['B'] = 2*df1['A']+2print(df1)df1.plot(kind='scatter',x='A',y='B')

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。