文章目录
Pandas高级操作
- 基础操作可观看我的另一篇博客笔记数据分析三剑客之Pandas(持续更新中…) 此篇是对这篇的补充!希望能够帮助到您~
1.替换操作
- 替换操作可以同步作用于Series和DataFrame中
单值替换
-
普通替换: 替换所有符合要求的元素:to_replace=15,value=‘e’
-
按
列指定单值
替换: to_replace={列标签:替换值} value=‘value’ -
示例如下
-
首先初始化一个
dataframe
-
df = DataFrame(data=np.random.randint(0,100,size=(5,6)))
-
out:
-
0 1 2 3 4 5 0 40 81 85 40 65 49 1 47 61 10 55 5 47 2 13 58 41 52 76 70 3 78 10 8 21 57 44 4 17 25 60 15 17 39
-
-
-
将dataframe里的
17
替换为Seventeen
-
df.replace(to_replace=17,value='Seventeen')
-
out df:
-
0 1 2 3 4 5 0 40 81 85 40 65 49 1 47 61 10 55 5 47 2 13 58 41 52 76 70 3 78 10 8 21 57 44 4 Seventeen 25 60 15 Seventeen 39 #里面的17都被替换成了seventeen
-
-
-
另一种形式,将
8
替换成eight
-
df.replace(to_replace={8:'eight'})
-
out df:
-
0 1 2 3 4 5 0 40 81 85 40 65 49 1 47 61 10 55 5 47 2 13 58 41 52 76 70 3 78 10 eight 21 57 44 4 17 25 60 15 17 39
-
-
-
如果我只想替换某一列的元素呢?将指定列的元素进行替换
to_replace={列索引:被替换的值}
-
df.replace(to_replace={4:5},value='five') #将索引为4列的5替换成five
-
out df
-
0 1 2 3 4 5 0 40 81 85 40 65 49 1 47 61 10 55 five 47 2 13 58 41 52 76 70 3 78 10 8 21 57 44 4 17 25 60 15 17 39
-
-
-
多值替换
-
列表替换: to_replace=[] value=[]
-
字典替换(推荐) to_replace={to_replace:value,to_replace:value}
-
示例如下:
-
列表替换多个值
-
df.replace(to_replace=[10,8,5],value=['ten','eight','five']) #依次替换10为ten,8为eight,5为five
-
out df
-
0 1 2 3 4 5 0 40 81 85 40 65 49 1 47 61 ten 55 five 47 2 13 58 41 52 76 70 3 78 ten eight 21 57 44 4 17 25 60 15 17 39
-
-
-
字典替换多个值
-
df.replace(to_replace={5:'five',60:'sixty'})
-
out df
-
0 1 2 3 4 5 0 40 81 85 40 65 49 1 47 61 10 55 five 47 2 13 58 41 52 76 70 3 78 10 8 21 57 44 4 17 25 sixty 15 17 39
-
-
-
2.映射操作
-
概念:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定(给一个元素值提供不同的表现形式)
-
函数:map(),map是Series的方法,只能被Series调用
-
使用示例如下:
map(dict字典)
-
创建一个df,两列分别是姓名和薪资,然后给其名字起对应的英文名
-
dic = { 'name':['张三','李四','张三'], 'salary':[15000,20000,15000] } df = DataFrame(data=dic) df
-
out df
-
name salary 0 张三 15000 1 李四 20000 2 张三 15000
-
-
-
现在我们要添加一列为name所对应的别名,而这个对应关系由一个字典来给出:
-
#映射关系表 dic = { '张三':'tom', '李四':'jack' }
-
-
再用map映射后的series赋值到源数据中,此series的值与源数据映射关系一一对应。
-
!!!注意,
map
只能由series
调用,因此别忘了取该列~-
df['e_name'] = df['name'].map(dic) df
-
out df:
-
name salary e_name 0 张三 15000 tom 1 李四 20000 jack 2 张三 15000 tom
-
-
map(函数)
-
我们可以实现自己的映射运算工具
-
例如:超过3000部分的钱缴纳50%的税,计算每个人的税后薪资
-
我们需要先定义一个处理函数
-
#该函数是我们指定的一个运算法则 def after_sal(s):#计算s对应的税后薪资 return s - (s-3000)*0.5
-
-
紧接着我们就可以用map调用此参数
-
df['after_sal'] = df['salary'].map(after_sal)#可以将df['salary']这个Series中每一个元素(薪资)作为参数传递给s df
-
out df:
-
name salary e_name after_sal 0 张三 15000 tom 9000.0 1 李四 20000 jack 11500.0 2 张三 15000 tom 9000.0
-
-
-
3.排序实现随机抽样
-
take() 将原始数据打乱
- 参数
axis
与drop
函数一样,列为1,行为0.
- 参数
-
np.random.permutation() 用于生成乱序的随机序列
-
示例:
-
首先初始化一个dataframe源数据。
-
df = DataFrame(data=np.random.randint(0,100,size=(100,3)),columns=['A','B','C']) df
-
out df
-
A B C 0 39 99 22 1 1 12 13 2 55 71 92 3 68 20 77 4 17 9 20 ... ... ... ... 95 1 54 56 96 76 6 6 97 78 41 63 98 23 17 34 99 65 16 82
-
-
-
接下来我们了解np.random.permutation()的作用
-
#生成乱序的随机序列 np.random.permutation(10)
-
out
-
array([7, 5, 8, 2, 6, 9, 0, 3, 1, 4]) #生成乱序的0~n-1
-
-
-
我们再了解take函数的作用:
-
df.take([2,0,1],axis=1)
-
out df:
-
C A B 0 22 39 99 1 13 1 12 2 92 55 71 3 77 68 20 4 20 17 9 ... ... ... ... 95 56 1 54 96 6 76 6 97 63 78 41 98 34 23 17 99 82 65 16
-
我们发现列的顺序变为了
take
第一个参数的隐式索引顺序。因此:我们可以利用生成乱序的随机序列函数np.random.permutation(3)
作为take的第一个参数,就能随机的将列打乱。-
df.take(np.random.permutation(3),axis=1)
-
-
-
-
-
了解原理后我们就可以运用了。
-
df.take(np.random.permutation(3),axis=1).take(np.random.permutation(100),axis=0)[0:6] #100项数据里我们取随机前6个
-
out df:
-
B C A 73 6 60 47 97 41 63 78 49 62 59 80 28 1 49 53 61 55 36 42 58 30 70 39
-
-
-
你看,我们成功实现了随机取样!!!
-
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]}) df
-
out df:
-
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
-
-
-
想要对水果的种类进行分析
-
print(df.groupby(by='item'))
-
out:
-
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x00000245300EF850>
-
返回的是一个对象!
-
-
-
我们可以用此对象的
groups
属性查看分组情况-
df.groupby(by='item').groups
-
out:
-
{'Apple': [0, 5], 'Banana': [1, 3], 'Orange': [2, 4]}
-
-
-
-
聚合示例
-
分组之后我们少不了聚合操作
-
上方分组操作我们已经了解了分组,接下来我们来了解聚合操作,其要配合分组使用.
-
分组之后我们
最好必须选中某列
,否则默认是对所有为数值型的列进行操作 -
计算出每一种水果的平均价格(选中price列进行mean操作)
-
df.groupby(by='item')['price'].mean()
-
out
-
item Apple 3.00 Banana 2.75 Orange 3.50 Name: price, dtype: float64
-
-
-
计算每一种颜色对应水果的平均重量
-
df.groupby(by='color')['weight'].mean()
-
out
-
color green 31.333333 red 12.000000 yellow 35.000000 Name: weight, dtype: float64
-
-
-
将计算出的平均重量汇总到源数据
-
我们知道上方聚合操作后返回的是一个
分组聚合后的Series,将它转换为字典
,就可以作为映射关系参数为map所使用,再添加到源数据中! -
操作如下:
-
dic = df.groupby(by='color')['weight'].mean().to_dict() df['mean_w'] = df['color'].map(dic) df
-
out df
-
item price color weight mean_w 0 Apple 4.0 red 12 12.000000 1 Banana 3.0 yellow 20 35.000000 2 Orange 3.0 yellow 50 35.000000 3 Banana 2.5 green 30 31.333333 4 Orange 4.0 green 20 31.333333 5 Apple 2.0 green 44 31.333333
-
-
-
-
高级数据聚合
-
使用groupby分组后,也可以使用
transform
和apply
提供自定义函数
实现更多的运算 -
df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
-
transform和apply都会进行运算,在transform或者apply中传入函数即可
-
transform和apply也可以传入一个lambda表达式
-
此方法可以实现自己的聚合方式,而不是只能运用系统自带的
sum
或者mean
等函数了 -
使用方法和mean,sum等聚合函数类似
-
示例如下:
-
自己创造一个求平均值的聚合函数
-
注意,因为是聚合函数,所以s是一个列表,用来接收多项分组数据。
-
def my_mean(s): m_sum = 0 for i in s: m_sum += i return m_sum / len(s)
-
transform()
-
df.groupby(by='item')['price'].transform(my_mean)
-
out:
-
0 3.00 1 2.75 2 3.50 3 2.75 4 3.50 5 3.00 Name: price, dtype: float64
-
apply()
-
df.groupby(by='item')['price'].apply(my_mean)
-
out:
-
item Apple 3.00 Banana 2.75 Orange 3.50 Name: price, dtype: float64
-
transform与apply的区别
-
我们发现
transform
返回的就是apply
通过映射后完成的Series
,方便直接添加到源数据列中 -
apply返回的是一个可以作为映射关系的
Series
,与原装mean()返回的是一样的。
5.透视表
-
透视表是一种可以对数据动态排布并且分类汇总的表格格式。或许大多数人都在Excel使用过数据透视表,也体会到它的强大功能,而在pandas中它被称作
pivot_table
。 -
透视表的优点:
- 灵活性高,可以随意定制你的分析计算要求
- 脉络清晰易于理解数据
- 操作性强,报表神器
-
pivot_table
有四个最重要的参数index
、values
、columns
、aggfunc
-
使用示例:
-
读取数据如下:
-
import pandas as pd import numpy as np df = pd.read_csv('../data/篮球赛.csv',encoding='utf8') df
-
out df
-
对手 胜负 主客场 命中 投篮数 投篮命中率 3分命中率 篮板 助攻 得分 0 勇士 胜 客 10 23 0.435 0.444 6 11 27 1 国王 胜 客 8 21 0.381 0.286 3 9 27 2 小牛 胜 主 10 19 0.526 0.462 3 7 29 3 灰熊 负 主 8 20 0.400 0.250 5 8 22 4 76人 胜 客 10 20 0.500 0.250 3 13 27 5 黄蜂 胜 客 8 18 0.444 0.400 10 11 27 6 灰熊 负 客 6 19 0.316 0.222 4 8 20 7 76人 负 主 8 21 0.381 0.429 4 7 29 8 尼克斯 胜 客 9 23 0.391 0.353 5 9 31 9 老鹰 胜 客 8 15 0.533 0.545 3 11 29 10 爵士 胜 主 19 25 0.760 0.875 2 13 56 11 骑士 胜 主 8 21 0.381 0.429 11 13 35 12 灰熊 胜 主 11 25 0.440 0.429 4 8 38 13 步行者 胜 客 9 21 0.429 0.250 5 15 26 14 猛龙 负 主 8 25 0.320 0.273 6 11 38 15 太阳 胜 客 12 22 0.545 0.545 2 7 48 16 灰熊 胜 客 9 20 0.450 0.500 5 7 29 17 掘金 胜 主 6 16 0.375 0.143 8 9 21 18 尼克斯 胜 主 12 27 0.444 0.385 2 10 37 19 篮网 胜 主 13 20 0.650 0.615 10 8 37 20 步行者 胜 主 8 22 0.364 0.333 8 10 29 21 湖人 胜 客 13 22 0.591 0.444 4 9 36 22 爵士 胜 客 8 19 0.421 0.333 5 3 29 23 开拓者 胜 客 16 29 0.552 0.571 8 3 48 24 鹈鹕 胜 主 8 16 0.500 0.400 1 17 26
-
以上是部分比赛数据
-
-
-
-
index参数:
分类汇总的分类条件
-
每个pivot_table必须拥有一个index。如果想查看哈登对阵每个队伍的得分则需要对每一个队进行分类并计算其各类得分的平均值:
-
想看看哈登对阵同一对手在不同主客场下的数据,分类条件为对手和主客场
-
df.pivot_table(index=['对手','主客场'])
-
-
-
values参数:需要对计算的数据进行筛选
-
如果我们只需要哈登在主客场和不同胜负情况下的得分、篮板与助攻三项数据:
-
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'])
-
out:
-
-
Aggfunc参数:设置我们对数据聚合时进行的函数操作
-
当我们未设置aggfunc时,它默认
aggfunc='mean'
计算均值。 -
获得
james harden
在主客场和不同胜负情况下的总得分、总篮板、总助攻时.-
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'],aggfunc='sum')
-
out:
-
-
-
Columns:可以设置列层次字段
-
对values字段进行分类
-
获取所有队主客场的总得分
-
df.pivot_table(index='主客场',values='得分',aggfunc='sum')
-
out:
-
-
获取每个队主客场的总得分(在总得分的基础上又进行了对手的分类)
-
df.pivot_table(index='主客场',values='得分',columns='对手',aggfunc='sum',fill_value=0)
-
out:
-
-
6.交叉表
-
是一种用于计算分组的特殊透视图,对数据进行汇总
-
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]}) df
-
out df
-
sex age smoke height 0 man 15 True 168 1 man 23 False 179 2 women 25 False 181 3 women 17 True 166 4 man 35 True 173 5 women 57 False 178 6 man 24 False 188 7 women 31 True 190 8 women 22 False 160
-
-
-
求出各个性别抽烟的人数
-
pd.crosstab(df.smoke,df.sex)
-
out:
-
-
求出各个年龄段抽烟人情况
-
pd.crosstab(df.age,df.smoke)
-
out:
'height':[168,179,181,166,173,178,188,190,160]})
df
-
out df
-
sex age smoke height 0 man 15 True 168 1 man 23 False 179 2 women 25 False 181 3 women 17 True 166 4 man 35 True 173 5 women 57 False 178 6 man 24 False 188 7 women 31 True 190 8 women 22 False 160
-
-
-
求出各个性别抽烟的人数
-
pd.crosstab(df.smoke,df.sex)
-
out:
- [外链图片转存中…(img-Vjt6TCmY-1722090049326)]
-
-
求出各个年龄段抽烟人情况
-
pd.crosstab(df.age,df.smoke)
-
out:
-
-
-