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主要支持谁