本篇主要记录一下pandas的高级操作
import numpy as np
import pandas as pd
from pandas import DataFrame,Series
生成数据:
df = DataFrame(data=np.random.randint(0,100,size=(4,5)))
df
替换操作:
# 将30替换为111
df.replace(to_replace=30, value=111)
to_replace表示要替换的值,values是替换后的值。
# 以字典的形式替换
df.replace(to_replace={0:'aaa',30:'thirty'})
# 修改指定行的数据
df.iloc[2]=[0,0,0,0,0]
df
映射操作
# map是Series的一个方法
# 概念:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定(给一个元素值提供不同的表现形式)
#创建一个df,两列分别是姓名和薪资,然后给其名字起对应的英文名
dic = {
'name':['张三','李四','王老五'],
'salary':[22222,7777,11111]
}
df = DataFrame(data=dic)
df
为每个人添加对应的英文名
dic = {
'张三':'tom',
'李四':'jay',
'王老五':'jerry'
}#映射关系表
df['English_name'] = df['name'].map(dic)
df
我们也可以把map当作运算工具
#把map当作运算工具
# 超过3000部分的钱缴纳50%的税,计算每个人的税后薪资
def after_tax(salary):
return salary-(salary-3000)*0.5
df['after_tax'] = df['salary'].map(after_tax)
df
apply操作:
apply也是df的一个运算工具,方法
作用:可以将df中行或者列数据进行某种形式的运算操作。
def func(s):
s = s.sum()
print(s)
df.apply(func,axis=0)
这里的sum将字符串进行了拼接,而数据相加
张三李四王老五 41110 tomjayjerry 25055.0
映射索引
- 使用rename()函数替换行索引
- 参数介绍:
- index 替换行索引
- columns 替换列索引
df2 = DataFrame({'color':['white','gray','purple','blue','green'],'value':np.random.randint(10,size = 5)})
df2
#映射关系表:映射df中的行索引
new_index = {0:'first',1:'two',2:'three',3:'four',4:'five'}
#替换索引
df2.rename(new_index)
# 替换列 注意要指定columns参数
new_col={'color':'cc','value':'vv'}
df2.rename(columns=new_col)
排序与随机抽样
- take()
- np.random.permutation()
np.random.permutation(10)
#输出
array([6, 9, 4, 8, 0, 7, 5, 3, 2, 1])
# 我们可以通过这种方式生成随机的索引
df3 = DataFrame(data=np.random.randint(0,100,size=(10,3)),columns=['A','B',"C"])
df3
# 生成乱序的索引序列
np.random.permutation(3) # array([2, 0, 1])
# 打乱数据排列
# take中只能用隐式索引(当索引非常多时,可以用随机生成,如果指定显式索引则有很多行要写),且轴向与drop一样,axis=0表示
df3.take([0,2,1], axis=1)
df3.take(np.random.permutation(3), axis=1)
# 打乱行
df3.take(np.random.permutation(10), axis=0)
数据的分类处理
- 数据分类处理的核心:
- groupby()函数
- groups属性查看分组情况
df4 = 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]})
df4
#计算出每一种水果的平均价格
df4.groupby(by='item')
# 通过group属性查看分组
df4.groupby(by='item').groups
{'Apple': Int64Index([0, 5], dtype='int64'),
'Banana': Int64Index([1, 3], dtype='int64'),
'Orange': Int64Index([2, 4], dtype='int64')}
# 查看平均值
df4.groupby(by='item').mean()
获取价格
# 获取价格
df4.groupby(by='item').mean()['price']
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64
#或者这种方式
df4.groupby(by='item')['price'].mean()
#将每种水果的平均价格数据汇总到原数据中
mean_price = df4.groupby(by='item')['price'].mean()
# 这样赋值是不行的,因为个数不一样
df4['mean_price'] = mean_price
df4
# 映射,把banana映射对应的价格2.75
# 但如果手写又太多,将它直接转成字典的映射关系
dic = mean_price.to_dict()
dic
{'Apple': 3.0, 'Banana': 2.75, 'Orange': 3.5}
df4['mean_price'] = df4['item'].map(dic)
df4
高级数据聚合
- 使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算
- df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
- transform和apply都会进行运算,在transform或者apply中传入函数即可
- transform和apply也可以传入一个lambda表达式
#通过transform自定义一个求均值的函数,作用到分组结果中
# transform返回数据直接汇总到数据中,而apply则需要经过映射一次
def my_mean(s):
sum = 0
for i in s:
sum+=i
return sum/s.size
df4.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
数据加载,读取txt文件
import pandas as pd
from pandas import DataFrame,Series
data=pd.read_csv('./data/type-.txt')
data
# 将文件中每一个词作为元素存放在DataFrame中
data=pd.read_csv('./data/type-.txt',sep='-',header=None)
data
连接数据库的操作如下
#连接数据库,获取连接对象
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('fruit',conn)
透视表
- 透视表是一种可以对数据动态排布并且分类汇总的表格格式。或许大多数人都在Excel使用过数据透视表,也体会到它的强大功能,而在pandas中它被称作pivot_table。
import pandas as pd
import numpy as np
df = pd.read_csv('./data/lanqiusai.csv')
df.head()
# 默认分类汇总使用的函数是mean
df.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')
#还想获得james harden在主客场和不同胜负情况下的平均得分、总篮板、最小助攻时
#不同的栏指定不同的方法
df.pivot_table(index=['主客场','胜负'],aggfunc={'得分':'mean','篮板':'sum','助攻':'min'})
#获取所有队主客场的总得分,默认情况下aggfunc='mean'
df.pivot_table(index='主客场', values='得分',aggfunc='sum')
#获取每个队主客场的总得分(在总得分的基础上又进行了对手的分类)
# columns 指定列层次的字段, fillna对空值进行填充
df.pivot_table(index='主客场',values='得分',aggfunc='sum',columns='对手').fillna(value=0)
交叉表
- 是一种用于计算分组的特殊透视图,对数据进行汇总
- pd.crosstab(index,colums)
- index:分组数据,交叉表的行索引
- columns:交叉表的列索引
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
#求出各个性别抽烟的人数
pd.crosstab(df.smoke,df.sex)
#求出各个年龄段抽烟人情况
pd.crosstab(df.age,df.smoke)