8、Python 数据分析-Pandas高级操作
1、替换操作replace()
- 替换操作可以同步作用于Series和DataFrame中
df = DataFrame(data=np.random.randint(0,20,size=(5,6)))
1.1、单值替换
- 普通替换: 替换所有符合要求的元素:to_replace=15,value='e'
#将1替换成one
df.replace(to_replace=1,value='one')
- 按列指定单值替换: to_replace={列标签:替换值} value='value'
df.replace(to_replace={0:1},value='one')
1.2、多值替换
- 列表替换: to_replace=[] value=[]
df.replace(to_replace=[0],value='one')
- 字典替换(推荐) to_replace=
df.replace(to_replace={0:'zero'})
2、映射操作map()
- 概念:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定(给一个元素值提供不同的表现形式)
创建一个df,两列分别是姓名和薪资,然后给其名字起对应的英文名
dic = {
'name':['张三','李四','张三'],
'salary':[15000,20000,15000]
}
df = DataFrame(data=dic)
映射关系表
dic = {
'张三':'tom',
'李四':'jay'
}
df['e_name'] = df['name'].map(dic)
- map是Series的方法,只能被Series调用
2.1、map运算操作
- 超过3000部分的钱缴纳50%的税,计算每个人的税后薪资
def after_sal(s):
return s - (s-3000)*0.5
df['after_sal'] = df['salary'].map(after_sal)
4、 排序实现的随机抽样take()
df = DataFrame(data=np.random.randint(0,100,size=(100,3)),columns=['A','B','C'])
np.random.permutation(5)
>>>
array([4, 3, 0, 2, 1])
#将原始数据打乱手动 indices列
# df.take(indices=[2,0,1],axis=1)
#将原始数据打乱获取前10条
df.take(indices=np.random.permutation(3),axis=1).take(indices=np.random.permutation(100),axis=0)[0:10]
5、数据的分类处理groupby()
-
数据分类处理的核心:
- groupby()函数
- groups属性查看分组情况
df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'],
'price':[4,3,3,2.5,4,2],
'color':['red','yellow','yellow','green','green','green'],
'weight':[12,20,50,30,20,44]})
返回原始数据分组之后的对象结果
df.groupby(by='item',axis=0)
>>>
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000020FABDB1EB8>
查看分组详情
df.groupby(by='item',axis=0).groups
>>>
{'Apple': Int64Index([0, 5], dtype='int64'),
'Banana': Int64Index([1, 3], dtype='int64'),
'Orange': Int64Index([2, 4], dtype='int64')}
计算每一种水果的平均价格
#方式一:
#df.groupby(by='item').mean()
df.groupby(by='item').mean()['price']
>>>
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64
#方式二: 推荐使用
mean_series = df.groupby(by='item')['price'].mean()
>>>
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64
将水果的平均价格汇总到源数据
dic = mean_series.to_dict()#装换成字典的格式
df['mean_price'] = df['item'].map(dic)
求出每一种颜色水果的平均重量,然后进行数据汇总
dic = df.groupby(by='color')['weight'].mean().to_dict()
df['mean_weight'] = df['color'].map(dic)
6、高级自定义数据聚合transform()|apply()
- 使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算
transform():直接汇总数据,进行映射,返回的是分组求和后的原dataframe的数据结构。
apply():进行映射,才能汇总数据,返回的是pandas的对象或者标量。
- df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
- transform和apply都会进行运算,在transform或者apply中传入函数即可
- transform和apply也可以传入一个lambda表达式
水果的平均价格
def my_mean(s):
sum = 0
for i in s:
sum += i
return sum / len(s)
df.groupby(by='item')['price'].transform(my_mean)
>>>
0 3.00
1 2.75
2 3.50
3 2.75
4 3.50
5 3.00
Name: price, dtype: float64
每一种水果的平均价格
def my_mean(s):
sum = 0
for i in s:
sum += i
return sum / len(s)
df.groupby(by='item')['price'].apply(my_mean)
>>>
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64
7、数据加载保存-数据库sqlite3
1、读取type-.txt文件数据
df = pd.read_csv('./data/type-.txt')
#查看维度
df.shape
>>>
(2, 1)
- 将文件中每一个词作为元素存放在DataFrame中
df = pd.read_csv('./data/type-.txt',sep='-',header=None)
df.shape
>>>
(3,3)
2、读取数据库中的数据
#连接数据库,获取连接对象
import sqlite3 as sqlite3
conn = sqlite3.connect('./data/weather_2012.sqlite')
#读取库表中的数据值
sql_df=pd.read_sql('select * from weather_2012',conn)
#将一个df中的数据值写入存储到db
df.to_sql('bbb',conn)
读取这个账
pd.read_sql('select * from bbb',conn)
8、透视表pivot_table()
-
透视表是一种可以对数据动态排布并且分类汇总的表格格式。或许大多数人都在Excel使用过数据透视表,也体会到它的强大功能,而在pandas中它被称作pivot_table。
-
透视表是一种进行分组统计的函数
-
透视表的优点:
- 灵活性高,可以随意定制你的分析计算要求
- 脉络清晰易于理解数据
- 操作性强,报表神器
import pandas as pd
import numpy as np
df = pd.read_csv('./data/透视表-篮球赛.csv',encoding='utf8')
pivot_table有四个最重要的参数index、values、columns、aggfunc
-
index参数:分类汇总的分类条件
- 每个pivot_table必须拥有一个index。如果想查看哈登对阵每个队伍的得分则需要对每一个队进行分类并计算其各类得分的平均值:
想看看哈登对阵同一对手在不同主客场下的数据,分类条件为对手和主客场
df.pivot_table(index=['对手','主客场'])
- values参数:需要对计算的数据进行筛选,
- 如果我们只需要哈登在主客场和不同胜负情况下的得分、篮板与助攻三项数据:
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'])
-
Aggfunc参数:设置我们对数据聚合时进行的函数操作
- 未设置aggfunc时,它默认aggfunc='mean'计算均值。
-
获得james harden在主客场和不同胜负情况下的总得分、总篮板、总助攻时:
方式一:
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'],aggfunc='sum')
方式二:
df.pivot_table(index=['主客场','胜负'],aggfunc={'得分':'sum','篮板':'sum','助攻':'sum'})
- Columns参数:可以设置列层次字段
- 对values字段进行分类
获取所有队主客场的总得分
df.pivot_table(index='主客场',values='得分',aggfunc='sum')
获取每个队主客场的总得分(在总得分的基础上又进行了对手的分类)
df.pivot_table(index='主客场',values='得分',aggfunc='sum',columns='对手',fill_value=0)
#fill_value空值填充为0
9、交叉表crosstab()
- 交叉表是特殊的透视表,统计分组频率时更方便
- 是一种用于计算分组的特殊透视图,对数据进行汇总,
- pd.crosstab(index,colums)
- index::要在行中分组的值
- columns:要在列中分组的值
- values:根据因子聚合的值数组,需指定aggfunc
- aggfunc:如指定,还需指定value
- normalize:将所有值除以值的总和进行归一化 ,为True时候显示百分比
df = DataFrame({'sex':['man','man','women','women','man','women','man','women','women'],
'age':[15,23,25,17,35,57,24,31,22],
'smoke':[True,False,False,True,True,False,False,True,False],
'height':[168,179,181,166,173,178,188,190,160]})
- 求出各个性别抽烟的人数
pd.crosstab(df.smoke,df.sex)
- 求出各个年龄段抽烟人情况
pd.crosstab(df.age,df.smoke)
10、apply与applymap区别
apply传递的是以series为基本单位,作用于行或列;
applymap传递的是以dataframe为基本单位,作用于每一个元素;
df = DataFrame(data=np.random.randint(0,100,size=(8,6)))
def my_func(s):
#参数s:df中的某一列
return s.mean()
df.apply(my_func,axis=0) #使用my_func处理df中每一列的数据
>>>
0 56.750
1 37.250
2 70.250
3 43.500
4 61.875
5 45.750
dtype: float64
def my_func1(s):
#参数s表示df中的每一个元素
return s+10 #对每一个元素进行+10操作
df.applymap(my_func1) #applymap就可以对df中的每一个元素进行操作