
Pandas高级操作
pandas数据分析库
数据转换
数据替换
替换操作可以作用于Series和DataFrame中
- 索引替换
import numpy as np
import pandas as pd
df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
index = list('ABCDEFHIJK'),
columns=['Python','Tensorflow','Keras'])
df.iloc[4,2] = None # 空数据
#重命名轴索引
df.rename(index = {'A':'AA','B':'BB'},columns = {'Python':'人工智能'})
- 值的替换
import numpy as np
import pandas as pd
df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
index = list('ABCDEFHIJK'),
columns=['Python','Tensorflow','Keras'])
df.iloc[4,2] = None # 空数据
# 替换值
df.replace(3,1024) #将3替换为1024
df.replace([0,7],2048) # 将0和7替换为2048
df.replace({0:512,np.nan:998}) # 根据字典键值对进行替换
df.replace({'Python':2},-1024) # 将Python这一列中等于2的,替换为-1024
数据映射
给Series中的一组数据提供另外一种表现形式,或者说给其绑定一组指定的标签或字符串。
- 创建一个df,两列分别是姓名和薪资,然后给其名字起对应的英文名
dic_data = {
'name':['zhangsan','lisi','wangwu','lisi'],
'salary':[10000,12000,8000,12000]
}
df = pd.DataFrame(data=dic_data)
#映射关系表
dic = {
'zhangsan':"jay",
'lisi':'tom',
'wangwu':'jerry'
}
df['e_name'] = df['name'].map(dic)
数据运算
map函数对Series数据的运算处理(map作为Series的运算工具)
- 超过3000部分的钱缴纳50%的税,计算每个人的税后薪资
def after_sal(s):
return s-(s-3000)*0.5
df['after_sal'] = df['salary'].map(after_sal)
提示:apply也可以像map一样充当运算工具,不过apply运算效率要远远高于map。因此在数据量级较大的时候可以使用apply。
apply函数对Series或DataFrame的运算处理
import numpy as np
import pandas as pd
df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
index = list('ABCDEFHIJK'),
columns=['Python','Tensorflow','Keras'])
df.iloc[4,2] = None # 空数据
#apply作用在Series中:可以对Series中的每一个元素进行运算处理
df['Keras'].apply(lambda x:True if x >5 else False)
#apply作用在DataFrame中:可以对df中的行或列进行运算处理
def convert(x): # 自定义方法
return (x.mean().round(1),x.count())
df.apply(convert,axis = 1)
applymap函数,DataFrame专有,对df中每一个元素进行运算处理
df.applymap(lambda x : x + 100)
transform高级运算工具
import numpy as np
import pandas as pd
df = pd.DataFrame(data = np.random.randint(0,10,size = (10,3)),
index = list('ABCDEFHIJK'),
columns=['Python','Tensorflow','Keras'])
# 1、对Series执行多项计算
df['Python'].transform([np.sqrt,np.exp]) # Series处理
def convert(x):
if x.mean() > 5:
x *= 10
else:
x *= -10
return x
# 2、对df执行不同计算
def convert(x):
if x.mean() > 5:
x *= 10
else:
x *= -10
return x
df.transform({'Python':convert,'Tensorflow':lambda x:np.min(x),'Keras':lambda x:np.max(x)}) # DataFrame处理
数学和统计方法
常用操作
import numpy as np
import pandas as pd
df = pd.DataFrame(data = np.random.randint(0,100,size = (20,3)),
index = list('ABCDEFHIJKLMNOPQRSTU'),
columns=['Python','Tensorflow','Keras'])
df.count() # 非NAN值的数量
df.max(axis = 0) #轴0最大值,即每一列最大值
df.min() #默认计算轴0最小值
df.median() # 中位数
df.sum() # 求和
df.mean(axis = 1) #轴1平均值,即每一行的平均值
df.cumsum() # 累加
df.cumprod() # 累乘
df.std() # 标准差
df.var() # 方差
df.quantile(q = [0.2,0.4,0.8]) # 分位数
df.describe() # 查看数值型列的汇总统计,计数、平均值、标准差、最小值、四分位数、最大值
df.pct_change()#将每个元素与其前一个元素进行比较,并计算前后数值的百分比变化
df['Python'].rank()#对序列中的元素值排名,该函数的返回值的也是一个序列,包含了原序列中每个元素值的名次。如果序列中包含两个相同的的元素值,那么会为其分配两者的平均排名
索引标签、位置获取
df['Python'].argmin() # 计算最小值位置
df['Keras'].argmax() # 最大值位置
df.idxmax() # 最大值索引标签
df.idxmin() # 最小值索引标签
数据排序
import numpy as np
import pandas as pd
df = pd.DataFrame(data = np.random.randint(0,30,size = (30,3)),
index = list('qwertyuioijhgfcasdcvbnerfghjcf'),
columns = ['Python','Keras','Pytorch'])
# 1、索引列名排序
df.sort_index(axis = 0,ascending=True) # 按索引排序,降序
df.sort_index(axis = 1,ascending=False) #按列名排序,升序
# 2、属性值排序
df.sort_values(by = ['Python']) #按Python属性值排序
df.sort_values(by = ['Python','Keras'])#先按Python,再按Keras排序
# 3、返回属性n大或者n小的值
df.nlargest(10,columns='Keras') # 根据属性Keras排序,返回最大10个数据
df.nsmallest(5,columns='Python') # 根据属性Python排序,返回最小5个数据
分箱操作
数据分箱(也称为离散分箱或分段)是一种数据预处理技术,用于减少次要观察误差的影响,是一种将多个连续值分组为较少数量的“分箱”的方法。说白了就是将连续型特征进行离散化。
分箱的实现
等距分箱
import pandas as pd import numpy as np age = np.arange(1,31,step=1) #连续性特征 #等距分箱 ret = pd.cut(age,bins=4) #bins表示分箱的箱子个数(分组数量) ret.value_counts() ret = pd.cut(age,bins=4,labels=['A','B','C','D']) #labels可以给每一个箱子起一个名字 #将分箱后的结果重新赋值给age,则age就被离散化 age = ret #可以给bins赋值一个列表,表示n个箱子的间距,就可以实现手动指定箱子的间距 age = np.arange(1,31,step=1) ret = pd.cut(age,bins=[1,10,20,25,30]) #labels可以给每一个箱子起一个名字 ret.value_counts()
等频分箱
x = np.random.random(size=(100,)) ret = pd.qcut(x,4) ret.value_counts() ret = pd.qcut(x,4,labels=['A','B','C','D']) ret.value_counts()
cut和qcut的区别:
1,cut: 按连续数据的大小分到各个桶里,每个桶里样本量可能不同,但是,每个桶相当于一个等长的区间,即:以数据的最大和最小为边界,等分成p个桶。
2,qcout: 与cut主要的区别就是每个桶里的样本数量是一定的。
随机抽样
- take()
- np.random.permutation()
df = pd.DataFrame(data=np.random.random(size=(100,4)),columns=['A','B','C','D'])
df.take(indices=np.random.permutation(4),axis=1).take(indices=np.random.permutation(100),axis=0)[0:20]
数据分组
- 数据分类处理的核心:
- groupby()函数
- groups属性查看分组情况
df = pd.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').groups #groups返回分组结果
df.groupby(by='item').mean() #mean聚合操作只会对数值型的数据进行聚合
df.groupby(by='item').mean()['price']
#聚合推荐方式
mean_price_s = df.groupby(by='item')['price'].mean()
#将每种水果的平均价格汇总到源数据中
dic = mean_price_s.to_dict()
df['mean_price'] = df['item'].map(dic)
使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算
apply和transform的区别:
- transform返回的结果是经过映射后的结果
- apply返回的是没有经过映射的结果
def myMean(p): sum = 0 for i in p: sum += i return sum / len(p) df.groupby(by='item')['price'].transform(myMean) df.groupby(by='item')['price'].apply(myMean)
agg实现对分组后的结果进行多种不同形式的聚合操作
df.groupby(by='item')['price'].agg(['max','min','sum'])
数据透视
透视表是一种可以对数据动态排布并且分类汇总的表格格式。或许大多数人都在Excel使用过数据透视表,也体会到它的强大功能,而在pandas中它被称作pivot_table。
pivot_table有四个最重要的参数index、values、columns、aggfunc
- index参数:分类汇总的分类条件
- 每个pivot_table必须拥有一个index。
df = pd.read_csv('./data/透视表-篮球赛.csv')
df.pivot_table(index=['对手','主客场'])
- values参数:需要对计算的数据进行筛选
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'])
- Aggfunc参数:设置我们对数据聚合时进行的函数操作
- 当我们未设置aggfunc时,它默认aggfunc='mean'计算均值。
#正常用法
df.pivot_table(index=['主客场','胜负'],values=['得分','篮板','助攻'],aggfunc='sum')
#变种用法
df.pivot_table(index=['主客场','胜负'],aggfunc={'得分':'sum','篮板':'max'})
- Columns:可以设置列层次字段
#获取所有队主客场的总得分
df.pivot_table(index=['主客场'],values='得分',aggfunc='sum')
#查看主客场下的总得分的组成元素是谁
df.pivot_table(index=['主客场'],values='得分',aggfunc='sum',columns='对手',fill_value=0)
项目案例1
手机销量分析:
import pandas as pd
data = pd.read_excel('./data/Phone.xlsx')
data.head()
#查看缺失数据的个数和占比
#查看缺失数据
for col in data.columns:
null_count = data[col].isnull().sum()
if null_count > 0:
p = str(null_count / data[col].size * 100)+'%'
print(col+':'+p)
#缺失值处理
data['年'] = data['订单日期'].dt.year
data['月'] = data['订单日期'].dt.month
#数据分箱:
#[0-16,17-26,27-36,37-49]
data['年龄段'] = pd.cut(data['年龄'],bins=[0,16,26,36,49])
#查看不同品牌手机的累计销量和累计销售额,且对累计销量进行降序
data.groupby(by='品牌')[['销售额','数量']].sum().sort_values('数量',ascending=False)
#查看不同品牌的不同型号数量
p_count_list = [] #品牌名称和品牌型号的数量
for p in data['品牌'].unique():
#可以将p表示品牌的行数据
p_df = data.loc[data['品牌'] == p]
p_count = p_df['型号'].nunique() #品牌对应不同型号的数量
p_count_list.append([p,p_count])
pd.DataFrame(p_count_list,columns=['品牌','型号数量'])
#查看不同品牌中价格最高和最低的型号是什么
data.groupby(by=['品牌','型号'])['价格'].agg(['max','min'])
#查看不同月份的销量情况,哪些月份销量比较高
data.groupby(by='月')['数量'].sum().sort_values(ascending=False)
#不同年龄段的购买力
data.groupby(by='年龄段')['数量'].sum().sort_values(ascending=False)
#查看不同省份不同城市的购买力情况
data.pivot_table(index=['省份名字','城市名字'],values='数量',aggfunc='sum').sort_values('数量',ascending=False)
项目案例2
美国大选政治现金分析:
- 加载数据
- 查看数据的基本信息
- 指定数据截取,将如下字段的数据进行提取,其他数据舍弃
- cand_nm :候选人姓名
- contbr_nm : 捐赠人姓名
- contbr_st :捐赠人所在州
- contbr_employer : 捐赠人所在公司
- contbr_occupation : 捐赠人职业
- contb_receipt_amt :捐赠数额(美元)
- contb_receipt_dt : 捐款的日期
- 对新数据进行总览,查看是否存在缺失数据
- 用统计学指标快速描述数值型属性的概要。
- 空值处理。可能因为忘记填写或者保密等等原因,相关字段出现了空值,将其填充为NOT PROVIDE
- 异常值处理。将捐款金额<=0的数据删除
- 新建一列为各个候选人所在党派party
- 查看party这一列中有哪些不同的元素
- 统计party列中各个元素出现次数
- 查看各个党派收到的政治献金总数contb_receipt_amt
- 查看具体每天各个党派收到的政治献金总数contb_receipt_amt
- 将表中日期格式转换为'yyyy-mm-dd'。
- 查看老兵(捐献者职业)DISABLED VETERAN主要支持谁
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员MarsXu
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果