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

1. pandas的数据结构

在这里插入图片描述

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等,用于分组的依据条件
axis0或者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提供的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

在这里插入图片描述

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()

Series的线形图

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

DataFrame的线形图

柱状图

柱状图一般用来描述各类别之间的关系。在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数据对象的柱状图:观察图很显然那个图和数据直接是有很明显的对应关系的,一行是一组图。

# 直接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)

hist直方图

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

kde密度图

散点图

散点图主要用来表示数据之间的规律,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')

scatter

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值