数据分析与可视化(四)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的数据结构

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第1张图片

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

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

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

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

2.索引

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

import pandas as pd
list1 = [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索引取值 1
s1 位置取值 1

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

import pandas as pd
dic = {
		'a':'中国',
		'b':'日本',
		'd':'美国'
}
s = pd.Series(dic, index=['a', 'b', 'c', 'd'])
print(s)

s.index = ['A', 'B', 'C','D']

#>>>>>>>结果:

a     中国
b     日本
c    NaN
d     美国
dtype: object
修改index: A     中国
B     日本
C    NaN
D     美国
dtype: object

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

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

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

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

  name location dynasty address  year
a   张飞       游走       蜀     NaN  1999
b  孙尚香       下路       蜀     NaN  2000
c   韩信       打野      战国     NaN  2020
d   貂蝉       中单       汉     NaN  2050
e   马超       上单       蜀     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)
#>>>>>>>结果:
True
     a   b   c    d     e
1   张飞  游走   蜀  NaN  1999
2  孙尚香  下路   蜀  NaN  2000
3   韩信  打野  战国  NaN  2020
4   貂蝉  中单   汉  NaN  2050
5   马超  上单   蜀  NaN  3030

3.索引的方法和属性

方法 属性
append 连接另一个Index对象,产生一个新的Index对象
diff 计算差集并得到一个Index
intersection 计算交集
union 计算并集
isin 计算一个指示各值是否都包含在参数集合中的布尔型数组
delete 删除索引i处的元素,并得到新的Index
drop 删除传入的值,并得到新的Index
insert 将元素插入索引i处,并得到新的索引
is_monotonic 当各元素均大于或等于前一个元素时,返回True
is.unique 当Index没有重复值时,返回True
unique 计算Index中唯一值的数组
df.index.insert(1,'w')
#>>>>>>>结果:
Index(['1', 'w', '2', '3', '4', '5'], dtype='object')

查看DataFrame的常用属性

属性 描述
values 元素,返回二维嵌套列表
index 索引,返回Index
columns 列名
dtypes 类型
ndim 维度
shape 形状
size 元素的个数
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    d     e
1   张飞  游走   蜀  NaN  1999
2  孙尚香  下路   蜀  NaN  2000
3   韩信  打野  战国  NaN  2020
4   貂蝉  中单   汉  NaN  2050
5   马超  上单   蜀  NaN  3030
--------------
[['张飞' '游走' '蜀' nan 1999]
 ['孙尚香' '下路' '蜀' nan 2000]
 ['韩信' '打野' '战国' nan 2020]
 ['貂蝉' '中单' '汉' nan 2050]
 ['马超' '上单' '蜀' nan 3030]]
--------------
Index(['1', '2', '3', '4', '5'], dtype='object')
--------------
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
--------------
a    object
b    object
c    object
d    object
e     int64
dtype: object
--------------
2
--------------
(5, 5)
--------------
25

2.Pandas的索引操作

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

重建索引
1.重建索引
import pandas as pd
import numpy as np
obj = pd.Series([3,4.5,9,0], index = ['a','c','b','d'])
print(obj)
obj.reindex(['a','b','c','d','e'])
》》》》》》结果:
a    3.0
c    4.5
b    9.0
d    0.0
dtype: float64
a    3.0
b    9.0
c    4.5
d    0.0
e    NaN
dtype: float64



###### 2.填充重建索引时引入的缺失值【前向与后向填充】

```python
#填充缺失值
obj.reindex(['a','c','c','d','e'], fill_value=10)
》》》》》》结果:
a     3.0
c     4.5
c     4.5
d     0.0
e    10.0
dtype: float64
#前向填充和后向填充:method='ffill\bfill'
obj1 = pd.Series(['blue','red','black'], index = [0,2,4])
obj1.reindex(np.arange(6), method = 'ffill')
>>>>>结果:
0     blue
1     blue
2      red
3      red
4    black
5    black
dtype: object

obj2 = pd.Series(['blue','red','black'], index = [0,2,4])
obj2.reindex(np.arange(6), method = 'bfill')
>>>>>结果:
0     blue
1      red
2      red
3    black
4    black
5      NaN
dtype: object
3.reindex操作
参数 说明
index 用于索引的新序列
method 插值(填充)方式【ffill[pad]、bfill[backfill]】
fill_value 缺失值替换值
limit 最大填充数
leve copy 在Multiindex的指定级别上匹配简单索引,否则取决其子集默认为True,无论如何都复制;如果为False,则新旧相等时不复制

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

更换索引

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

data = {
	'name':['张飞', '孙尚香', '韩信', '貂蝉', '马超'],
	'location':['游走', '下路', '打野', '中单', '上单'],
	'dynasty':['蜀', '蜀', '战国', '汉', '蜀'],
	'year':[1999, 2000, 2020, 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  year
dynasty                            
蜀         张飞       游走     NaN  1999
蜀        孙尚香       下路     NaN  2000
战国        韩信       打野     NaN  2020
汉         貂蝉       中单     NaN  2050
蜀         马超       上单     NaN  3030

3.DataFrame数据的查询和编辑

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

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

#选取列
import pandas as pd
import numpy as np
data = {
    '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 address
0   张三   21      兰州
1   李四   19      上海
2  王麻子   23      北京
以列名取一列数据:
 0     张三
1     李四
2    王麻子
Name: name, dtype: object
以列名取两份数据:
   name  age
0   张三   21
1   李四   19
2  王麻子   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 address
0   张三   21      兰州
1   李四   19      上海
显示2行:
   name  age address
1   李四   19      上海
  name  age address
0   张三   21      兰州
1   李四   19      上海
2  王麻子   23      北京
  name  age address
0   张三   21      兰州
  name  age address
0   张三   21      兰州
1   李四   19      上海
2  王麻子   23      北京
  name  age address
2  王麻子   23      北京
  name  age address
2  王麻子   23      北京
1   李四   19      上海
3.读取行和列

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

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

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

#loc
data = {
	'name':['张飞', '孙尚香', '韩信', '貂蝉', '马超'],
	'location':['游走', '下路', '打野', '中单', '上单'],
	'dynasty':['蜀', '蜀', '战国', '汉', '蜀'],
	'year':[1999, 2000, 2020, 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  year
dynasty                            
蜀         张飞       游走     NaN  1999
蜀        孙尚香       下路     NaN  2000
战国        韩信       打野     NaN  2020
汉         貂蝉       中单     NaN  2050
蜀         马超       上单     NaN  3030
取name和year两列的数据:
         name  year
dynasty           
蜀         张飞  1999
蜀        孙尚香  2000
战国        韩信  2020
汉         貂蝉  2050
蜀         马超  3030
取汉,战国行中name,year的数据:
         name  year
dynasty           
汉         貂蝉  2050
战国        韩信  2020
#iloc  [索引0开始]
print("显示前两列:\n", df2.iloc[:, 2])
print("显示第1和第3行的第2列:\n", df2.iloc[[1,3],[0]])
显示前两列:
 dynasty
蜀     19992000
战国    202020503030
Name: year, dtype: int64
显示第1和第3行的第二列:
         name
dynasty     
蜀        孙尚香
汉         貂蝉

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

4.布尔选择

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

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

dynasty
蜀     FalseTrue
战国    FalseFalseFalse
Name: name, dtype: bool
编辑【提取需要编辑的数据,重新赋值】
1.增加数据

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

#插入一行数据append
#加列并赋值
df1['C'] = 10
df1['age'] = [24,33,19,40,80]

data1 = {
    'name':'李白',
    'location':'打野',
    'dynasty':'唐',
    'year':'1909'
}
df1.append(data1,ignore_index=True)
  name location dynasty  year   C  age
0   张飞       游走       蜀  1999  10   24
1  孙尚香       下路       蜀  2000  10   33
2   韩信       打野      战国  2020  10   19
3   貂蝉       中单       汉  2050  10   40
4   马超       上单       蜀  3030  10   80

name	location	dynasty	year	C	age
0	张飞	游走	蜀	1999	10.0	24.0
1	孙尚香	下路	蜀	2000	10.0	33.0
2	韩信	打野	战国	2020	10.0	19.0
3	貂蝉	中单	汉	2050	10.0	40.0
4	马超	上单	蜀	3030	10.0	80.0
5	李白	打野	唐	1909	NaN
2.删除数据

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

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

df1.drop('C',axis=1,inplace=True)
print(df1)

  name location dynasty  year  age
0   张飞       游走       蜀  1999   24
1  孙尚香       下路       蜀  2000   33
2   韩信       打野      战国  2020   19
3   貂蝉       中单       汉  2050   40
4   马超       上单       蜀  3030   80
3.修改数据

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

4.pandas数据运算

算术运算

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

import pandas as pd
import 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    1
b    4
d   -1
e    9
f    0
g   -8
dtype: int64
obj2:
 a     4
c     9
d     0
e    -4
f    -1
h    10
dtype: int64
a    5.0
b    NaN
c    NaN
d   -1.0
e    5.0
f   -1.0
g    NaN
h    NaN
dtype: float64

## DataFrame  行和列均会对齐给NaN值
import pandas as pd
import numpy as np
df1 = 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   d
A  0  1   2   3
B  4  5   6   7
C  8  9  10  11
df1:
    a  c  d
A  0  1  2
B  3  4  5
D  6  7  8
     a   b     c     d
A  0.0 NaN   3.0   5.0
B  7.0 NaN  10.0  12.0
C  NaN NaN   NaN   NaN
D  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 price
0   apple   301   grape   402  banana   50元
    fruit price
0   apple    30
1   grape    40
2  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         c
app -0.336255 -0.446342 -0.888068
win  2.742748  2.432790 -1.444682
mic  0.567298 -0.268666  0.039183

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

a	b	c
app	-0.336	-0.446	-0.888
win	2.743	2.433	-1.445
mic	0.567	-0.269	0.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   -9
a   -1
c    0
d    5
e    9
dtype: int64
索引降序:
 e    9
d    5
c    0
b   -9
a   -1
dtype: int64

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

#DataFrame
print(df)
print(df.sort_values(by='a'))
            a         b         c
app -0.336255 -0.446342 -0.888068
win  2.742748  2.432790 -1.444682
mic  0.567298 -0.268666  0.039183
            a         b         c
app -0.336255 -0.446342 -0.888068
mic  0.567298 -0.268666  0.039183
win  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         c
app -0.336255 -0.446342 -0.888068
win  2.742748  2.432790 -1.444682
mic  0.567298 -0.268666  0.039183
按列汇总:
 a    2.973791
b    1.717783
c   -2.293567
dtype: float64
按行汇总:
 app   -1.670665
win    3.730856
mic    0.337815
dtype: float64

2.数据的描述与统计

描述性统计表:

方法名称 说明 方法名称 说明
min 最小值 max 最大值
mean 均值 ptp 极差
std 标准差 var 方差
cov 协方差 sem 标准误差
median 中位数 mode 众数
skew 样本偏度 kurt 样本峰度
quantitle 四分位数 count 非空值数目
describe 统计描述 mad 平均绝对离差

对于类别型特征的描述性统计,可以使用频数统计表。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    3
3    2
1    1
2    1
5    1
6    1
dtype: int64

5.数据分组与聚合

数据分组

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

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

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

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

#取df['data1']这一列数据并按df['key1']这一列的数据来分组  分完之后a:3 ,b:2
import numpy as np
import 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  key2     data1     data2
0    a     1  0.410518  0.204681
1    a     0 -0.558132 -0.008501
2    b     1 -0.008334 -1.935630
3    b     1 -0.481743  0.775196
4    a     0  0.597605  0.561882
key1
a    3
b    2
Name: data1, dtype: int64
key1
a    0.149997
b   -0.245038
Name: data1, dtype: float64

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

#按列索引名称分组
grouped1 = df.groupby('key1').size()
grouped2 = df.groupby('key1').mean()
print(grouped1)
grouped2
key1
a    3
b    2
dtype: int64

key2	data1	data2
key1			
a	0.333333	0.149997	0.252688
b	1.000000	-0.245038	-0.580217

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

##所给的按列表或元组
w = ['w','w','y','w','y']
df.groupby(w).sum()

key2	data1	data2
w	2	-0.629356	0.971377
y	1	0.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         4
a -0.422562  1.962075 -0.489384 -1.304302 -1.109478
b  1.134703 -0.358548 -1.373025  0.851012 -0.302279
A -0.196233 -0.192463  0.286070  0.872550 -0.835654
B -0.038677 -0.130829 -0.599642 -0.201865 -1.849057
c -0.033203 -0.512046 -0.414564  0.516591  1.191699
C -1.145768  0.176744 -0.160164  1.435075 -0.124890
              0         1         2         3         4
one   -0.618795  1.769613 -0.203314 -0.431753 -1.945131
three -1.178971 -0.335301 -0.574728  1.951666  1.066808
two    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         3
0  0.714710 -1.180971  0.177371  1.257526
1 -0.465390  0.822470  1.767948  0.740839
2  0.194928  0.658354 -0.053870 -0.657892
3  1.001120 -1.195080  1.122340 -1.813876

a    1.998365
b   -2.471768
Name: 3, dtype: float64
数据聚合:对分组后的数据进行计算,产生标量值的数据转换过程。

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

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

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    否    否     20092017     2.4    8.5    NaN   
1    2****1984110000    否    否     20152017     1.8    5.8    NaN   
2    3****1983060000    否    否     20132017     2.0    5.6    NaN   
3    4****1985040000    否    否     20142017     2.5    6.6    NaN   
4    5****1986040000    否    否     20142017     1.3    5.2    NaN   

   血小板计数  
0  248.0  
1  300.0  
2  195.0  
3  252.0  
4  169.0  
求当前数据的各项统计量:
            淋巴细胞计数        白细胞计数
sum   4280.270000  6868.008100
mean     3.849164     6.176266
求个字段的不同统计量:
 淋巴细胞计数     3.849164
白细胞计数     12.043418
dtype: float64
计算不同字段不同数目的统计量:
         淋巴细胞计数      白细胞计数
mean  3.849164   6.176266
std        NaN  12.043418
统计不同性别人群的血小板计数:
 性别
女    212.687636194.727417
Name: 血小板计数, dtype: float64
统计不同性别人群的血小板计数:
   性别       血小板计数
0212.687636
1194.727417

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

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

# 分组运算
## transform  运算分布到每一行
data.groupby('性别')['血小板计数'].transform('mean').sample(5)


915     194.727417
1039    194.727417
1062    194.727417
95      194.727417
416     212.687636
Name: 血小板计数, dtype: float64

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

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


性别  是否吸烟
女   否       212.133188297.333333
男   否       194.236749195.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')

参数 使用说明
data 接收DataFrame,创建表的数据
values 接收string,指定聚合的数据字段,默认全部
index 接收string或list,行分组键
columns 接收string或list,列分组键
aggfunc 接收函数,表示聚合函数,默认mean
margins 接收boolean,表示汇总功能开关
dropna 接收boolean,表示是否删除掉全为NaN的列,默认False
import numpy as np
import pandas as pd
data = 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')
  k1     k2         w         y
0   a    one  0.505038 -0.692691
1   b    two  0.760838 -1.147333
2   c  three  0.279918 -0.511096
3   a    one  0.361962  0.605746
4   c    two  0.605619  0.217253
5   d  three  0.708927  1.632609
6   e  three  0.760684 -0.099134
7   b  three  0.678767  0.814771
8   d    one  0.062156 -1.247613
9   c    two  0.800672  3.008441
10  a    one  0.958991 -0.014311
11  c    two  0.943706  0.486200

w	y
k2	one	three	two	one	three	two
k1						
a	0.608664	NaN	NaN	-0.033752	NaN	NaN
b	NaN	0.678767	0.760838	NaN	0.814771	-1.147333
c	NaN	0.279918	0.783332	NaN	-0.511096	1.237298
d	0.062156	0.708927	NaN	-1.247613	1.632609	NaN
e	NaN	0.760684	NaN	NaN	-0.099134	NaN

由于复制过不来表格 就截屏了 前面遇到过好几次透视表了,groupby出来的都是透视表。
数据分析与可视化(四)Pandas学习基础一:统计分析基础_第2张图片

分类汇总求和

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第3张图片

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

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

参数 使用说明
index 接收string或者list,表示行索引键,没有默认值
columns 接收string或者list,表示列索引键,没有默认值
values 接收array,表示聚合数据,默认为None
rownames 表示行分组键名,无默认
colnames 表示列分组键名,无默认
aggfunc 接收函数,表示聚合函数,默认None
margins 接收boolean,表示汇总功能开关
dropna 接收boolean,表示删除的全为NaN的列,默认False
normalize 接收boolean,表示是否对值进行标准化,默认False
##交叉表
pd.crosstab(data.k1,data.k2,margins=True)#在边框处增加汇总


k2	one	three	two	All
k1				
a	3	0	0	3
b	0	1	1	2
c	0	1	3	4
d	1	1	0	2
e	0	1	0	1
All	4	4	4	12

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第4张图片

7.Pandas可视化

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

线形图

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

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

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第5张图片

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

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第6张图片

柱状图

柱状图一般用来描述各类别之间的关系。在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))

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第7张图片
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')

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第8张图片

直方图和密度图

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

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

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第9张图片

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

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第10张图片

散点图

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

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

数据分析与可视化(四)Pandas学习基础一:统计分析基础_第11张图片

你可能感兴趣的:(#,python可视化,python数据分析与数据挖掘,python,pandas,数据分析)