数据分析之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() 将原始数据打乱

    • 参数axisdrop函数一样,列为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分组后,也可以使用transformapply提供自定义函数实现更多的运算

  • 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有四个最重要的参数indexvaluescolumnsaggfunc

  • 使用示例:

    • 读取数据如下:

      • 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:

        -在这里插入图片描述

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值