pandas高级操作
需要导入的模块
import numpy as np
import pandas as pd
from pandas import DataFrame
1.替换操作
替换操作可以同步作用于Series和DataFrame中
-
单值替换
- 普通替换: 替换所有符合要求的元素:to_replace=15,value='e'
- 按列指定单值替换: to_replace={列标签:替换值} value='value'
-
多值替换
- 列表替换: to_replace=[] value=[]
- 字典替换(推荐) to_replace={to_replace:value,to_replace:value}
df = DataFrame(data=np.random.randint(0,50,size=(7,5)))
#输出结果:
0 1 2 3 4
0 43 13 49 13 28
1 38 32 9 5 11
2 3 17 5 27 33
3 26 40 39 3 19
4 40 27 12 37 38
5 39 11 22 25 44
6 23 42 6 9 10
#单值替换
df.replace(to_replace=6,value='six')
#输出结果:
0 1 2 3 4
0 43 13 49 13 28
1 38 32 9 5 11
2 3 17 5 27 33
3 26 40 39 3 19
4 40 27 12 37 38
5 39 11 22 25 44
6 23 42 six 9 10
#多值替换 字典替换
df.replace(to_replace={6:'six',3:'two'})
#输出结果:
0 1 2 3 4
0 43 13 49 13 28
1 38 32 9 5 11
2 two 17 5 27 33
3 26 40 39 two 19
4 40 27 12 37 38
5 39 11 22 25 44
6 23 42 six 9 10
#定列替换 to_replace={列标签:替换值} value='value'
df.replace(to_replace={2:5},value='five')
#输出结果:
0 1 2 3 4
0 43 13 49 13 28
1 38 32 9 5 11
2 3 17 five 27 33
3 26 40 39 3 19
4 40 27 12 37 38
5 39 11 22 25 44
6 23 42 6 9 10
2.映射操作
- 概念:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定(给一个元素值提供不同的表现形式)
# 创建一个df,两列分别是姓名和薪资,然后给其名字起对应的英文名
dic = {
'name':['jay','tom','jay'],
'salary':[1000,2000,1000]
}
df = DataFrame(data=dic)
#输出结果:
name salary
0 jay 1000
1 tom 2000
2 jay 1000
#给jay和tom起两个中文名字
#映射关系表
dic = {
'jay':'张三',
'tom':'李四'
}
df['c_name'] = df['name'].map(dic)
#输出结果:
name salary c_name
0 jay 1000 张三
1 tom 2000 李四
2 jay 1000 张三
强调:map是Series的方法,只能被Series调用
2. 运算工具
- 超过3000部分的钱缴纳50%的税,计算每个人的税后薪资
def after_sal(s):
return s-(s-3000)*0.5
dic['after_sal']=df['salary'].map(after_sal)
#输出结果:
name salary c_name after_sal
0 jay 1000 张三 650.0
1 tom 2000 李四 1150.0
2 jay 1000 张三 650.0
Series的方法apply也可以像map一样充当运算工具
- apply充当运算工具效率要远远高于map
def after_sal(s):
return s-(s-3000)*0.5
dic['after_sal']=df['salary'].apply(after_sal)
#输出结果:
name salary c_name after_sal
0 jay 1000 张三 650.0
1 tom 2000 李四 1150.0
2 jay 1000 张三 650.0
3.排序实现的随机抽样take()
- take()
- np.random.permutation()
df = DataFrame(data=np.random.randint(0,100,size=(100,3)),columns=['A','B','C'])
np.random.permutation(3) #返回0-2之间的乱序序列
#对原始数据进行打乱即对索引打乱
#task的axis和drop系列的函数
df.take(indices=np.random.permutation(3),axis=1)
#对行列索引进行打乱且进行随机抽样
df.take(indices=np.random.permutation(3),axis=1).take(indices=np.random.permutation(100),axis=0)[0:20]
4.数据的分类处理
- 数据分类处理的核心:
- 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]})
#输出结果:
item price color weight
0 Apple 4.0 red 12
1 Banana 3.0 yellow 20
2 Orange 3.0 yellow 50
3 Banana 2.5 green 30
4 Orange 4.0 green 20
5 Apple 2.0 green 44
#按水果的种类分组
df.groupby(by='item')
#查看分组结果
df.groupby(by='item').groups
#分组聚合:计算每一种水果的平均价格
#方式1:不推荐
df.groupby(by='item').mean()['price']
#方式2:推荐
df.groupby(by='item')['price'].mean()
#输出结果:
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64
#将每一种水果的平均价格汇总到源数据中
#平均价格
mean_price = df.groupby(by='item')['price'].mean()
#转换成字典格式
dic = mean_price.to_dict()
#输出结果:{'Apple': 3.0, 'Banana': 2.75, 'Orange': 3.5}
df['mean_price'] = df['item'].map(dic)
#输出结果:
item price color weight mean_price
0 Apple 4.0 red 12 3.00
1 Banana 3.0 yellow 20 2.75
2 Orange 3.0 yellow 50 3.50
3 Banana 2.5 green 30 2.75
4 Orange 4.0 green 20 3.50
5 Apple 2.0 green 44 3.00
#求出每一种颜色水果的平均重量,将其汇总到源数据中
#平均重量
mean_weight=df.groupby(by='color')['weight'].mean()
#转换成字典格式
dic=mean_weight.to_dict()
df['mean_weight'] = df['item'].map(dic)
#输出结果:
item price color weight mean_price color_mean_weight
0 Apple 4.0 red 12 3.00 12.000000
1 Banana 3.0 yellow 20 2.75 35.000000
2 Orange 3.0 yellow 50 3.50 35.000000
3 Banana 2.5 green 30 2.75 31.333333
4 Orange 4.0 green 20 3.50 31.333333
5 Apple 2.0 green 44 3.00 31.333333
5.高级数据聚合
- 使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算
- 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
df.groupby(by='item')['price'].apply(my_mean)
#输出结果:
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64
apply和transform的区别:
- transform返回的结果是经过映射后的结果
- apply返回的是没有经过映射的结果
6.数据加载
- 读取type-.txt文件数据
#将文件中每一个词作为元素存放在DataFrame中
df = pd.read_csv('./type-.txt',header=None,sep='-')
#输出结果:
0 1 2
0 你好 我好 他也好
1 也许 大概 有可能
2 然而 未必 不见得
- 读取数据库中的数据
#连接数据库,获取连接对象
import sqlite3 as sqlite3
conn= sqlite3.connect('./weather_2012.sqlite')
#读取库表中的数据值
sql_df=pd.read_sql('select * from weather_2012',conn)
sql_df.head()
#输出结果:
index Date/Time Temp (C) Dew Point Temp (C) Rel Hum (%) Wind Spd (km/h) Visibility (km) Stn Press (kPa) Weather
0 0.0 2012-01-01 00:00:00 -1.8 -3.9 86.0 4.0 8.0 101.24 Fog
1 1.0 2012-01-01 01:00:00 -1.8 -3.7 87.0 4.0 8.0 101.24 Fog
2 2.0 2012-01-01 02:00:00 -1.8 -3.4 89.0 7.0 4.0 101.26 Freezing Drizzle,Fog
3 3.0 2012-01-01 03:00:00 -1.5 -3.2 88.0 6.0 4.0 101.27 Freezing Drizzle,Fog
4 4.0 2012-01-01 04:00:00 -1.5 -3.3 88.0 7.0 4.8 101.23 Fog
#将一个df中的数据值写入存储到db
df.to_sql('dd',conn)
pd.read_sql('select * from dd',conn)
#输出结果:
index 0 1 2
0 0 你好 我好 他也好
1 1 也许 大概 有可能
2 2 然而 未必 不见得
7.透视表pivot_table
透视表是一种可以对数据动态排布并且分类汇总的表格格式
透视表的优点:
- 灵活性高,可以随意定制你的分析计算要求
- 脉络清晰易于理解数据
- 操作性强,报表神器
df = pd.read_csv('./透视表-篮球赛.csv',engine='python',encoding='utf-8')
pivot_table有四个最重要的参数index、values、columns、aggfunc
-
index参数:分类汇总的分类条件
每个pivot_table必须拥有一个index
# 哈登对阵同一对手在不同主客场下的数据,分类条件为对手和主客场
df.pivot_table(index=['对手','主客场'])
- values参数:需要对计算的数据进行筛选
# 哈登在主客场和不同胜负情况下的得分、篮板与助攻三项数据
df.piovt_table(index=['主客场','胜负',values=['得分','篮板','助攻']])
#输出结果:
助攻 得分 篮板
主客场 胜负
主 胜 10.555556 34.222222 5.444444
负 8.666667 29.666667 5.000000
客 胜 9.000000 32.000000 4.916667
负 8.000000 20.000000 4.000000
- Aggfunc参数:设置我们对数据聚合时进行的函数操作。未设置,默认aggfunc='mean'
#james harden在主客场和不同胜负情况下的总得分、总篮板、总助攻时
#方式1:
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'],aggfunc='sum')
#方式2
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)
8.交叉表
- 是一种用于计算分组的特殊透视图,对数据进行汇总
- pd.crosstab(index,colums)
- index:分组数据,交叉表的行索引
- columns:交叉表的列索引
import pandas as pd
from pandas import DataFrame
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(index=df.smoke,columns=df.sex)
#求出各个年龄段抽烟人情况
pd.crosstab(df.age,df.smoke)