Pandas数据处理

数据预览
  • 首先,调用read_excel()方法读取数据

    import pandas as pd
    df = pd.read_excel("data.xlsx")
    df
    
    	姓名	班级	语文	数学
    0	张三	一班	99	  90
    1	李四	一班	78	  NaN
    2	王五	一班	70	  88
    3	小明	二班	88	  99
    4	小红	二班	98	  77
    
  • 导入数据后,首先要熟悉数据。

    • shape属性:可以帮助我们查看数据包含几行几列

      df.shape
      (5,4)
      

      从结果可以看出,这份数据一共有5行4列

    • **head()tail()**方法:head()方法可以帮助我们查看数据的前几行,tail()方法可以帮助我们查看数据的后几行

      df.head()
      	姓名	班级	语文	数学
      0	张三	一班	99	  90
      1	李四	一班	78	  NaN
      2	王五	一班	70	  88
      3	小明	二班	88	  99
      4	小红	二班	98	  77
      
      df.tail(2)
      	姓名	班级	语文	数学
      3	小明	二班	88	  99
      4	小红	二班	98	  77
      

      head()方法默认展示的是前5行数据,tail()方法默认展示的是后5行数据。当他们传入指定数字时,就可以帮我们获取指定的行数。

    • dtypes属性:可以帮助我们查看每列数据的数据类型

      df.dtypes
      姓名	object
      班级	object
      语文	int64
      数学	int64
      dtype object
      

      object类型是字符串,int64是整型,float64是浮点型

    • **describe()**方法:可以帮助我们查看数值型变量的描述性统计量

      df.describe()
      		语文	数学
      count
      mean
      std
      min
      25%
      50%
      75%
      max
      

      count表示计数,mean表示平均值,std表示标准差,minmax分别表示最小值和最大值,25%50%75%表示四分位数

    • **info()**方法:可以帮助我们查看数据的列名、数据类型、非空值、以及内存占用情况

      df.info()
      <class "pandas.core.frame.DataFrame">
      RangeIndex: 6 entries, 0 to 5
      Data columns (total 5 columns):
      #	Column	Non-Null Count	Dtype
      --	-----	-------	-----	-----
      0	姓名	    6 non-null	  object			
      1	班级	    6 non-null	  object
      2	语文	    6 non-null	  int64
      3	数学	    5 non-null	  int64
      dtypes: int64(2),object(2)
      memory usage: 368.0+ bytes
      

      可以清楚的看到每一个列字段的列名、非空值和数据类型。另外“数学”这一列只有5个非空值,表明该列存在缺失值。同时memory usage为我们展示了这份数据占用内存的大小

数据预处理

通过数据预览,可以做到对数据心中有数。然而,在正式进行数据处理之前,我们必须进行数据预处理,它直接关系到分析结果的准确性。

有些数据会存在缺失值(NaN)、重复值

  • 检测缺失值

    • 其实检测缺失值最简单的方法就是调用**info()**方法,通过观察每一列的非空值,即可判断出哪些列存在缺失值

    • 另外还有一种检测是否存在缺失值的方法,即**isnull()方法搭配any()**方法,具体介绍如下

      • isnull():对于缺失值,返回True;对于非缺失值,返回False

      • any():一个序列中有一个True,则返回True,否则返回False

        df.isnull()					###打印出每个数据的True或False值
        
        	姓名	   班级	 语文	    数学	  英语
        0	False	False	False	False	False
        1	False	False	False	True	False
        2	False	False	False	False	False
        3	False	False	False	False	False
        4	False	False	False	False	False
        5	False	False	False	False	False
        
        df.isnull().any(axis=1)			###axis=1,可以帮助我们打印出每一行是否存在缺失值
        
        0	False
        1	True
        2	False
        3	False
        4	False
        5	False
        
        df.isnull().any()				###不指定打印的是每一列 是否存在缺失值
        姓名	False
        班级	False
        语文	False
        数学	True
        英语	False
        
  • 检测重复值

    • 调用**duplicated()**方法,可以用于检测重复值

      df.duplicated()
      0	False	
      1	False
      2	True
      3	False
      4	False
      5	False
      
      df.duplicated().any()
      True
      

      调用duplicated()方法,可以返回某一行是否是重复值。由于第4行和第3行的数据属于重复行,因此返回True。接着使用any()方法,即可判断出数据中存在重复值

  • 缺失值处理

    • 通常使用NaN表示缺失值。如果存在缺失值,我们可以调用**fillna()方法来填充数据。也可以用dropna()**方法删除缺失值

      df = df.fillna(0)	###将NaN修改为0
      df = df.dropna()	###将有缺失值的一行删除
      
  • 重复值处理

    • **drop_duplicates()**方法,它可以对所有值进行重复值判断,并默认保留第一个(行)值

      df
      	姓名	年龄
      0	张三	19
      1	张三	19
      2	李四	20
      
      df = df.drop_duplicates()
      	姓名	年龄
      0	张三	19
      2	李四	20
      

      可以帮我们删除重复行,只保留第一行的数据

  • 数据替换

    • 调用**replace()**方法,可以实现数据替换,例如replace(A,B),表示直接将A替换成B

      df['数学'] = df['数学'].replace(0,90)
      
数据选取
  • 按行/列筛选,lociloc两种方法,用于行/列筛选

    • loc:利用标签索引的方式获取行或列

    • iloc:利用位置索引的方式获取行或列

      选取一列
      df['f']
      df.loc[:,'f']
      df.iloc[:,[1]]
      
      选取多列
      df[['e','f']]
      df.loc[:,['e','f']]
      df.iloc[:,[0,1]]
      
      选取一行
      df.loc['b',:]
      df.iloc[1,:]
      
      选取多行
      df.loc[['a','b'],:]
      df.iloc[[0,1],:]
      
      同时选取行列
      df.loc['b','f']
      df.iloc[1,1]
      
      同时选取多行多列
      df.loc[['a','b'],['f','g']]
      df.iloc[[0,1],[1,2]]
      
      df = df.set_index("姓名")
      df
      
      		班级	 语文	 数学	  英语
      姓名
      赵一	  一班	98	 96.0	97
      王二	  一班	88	 90.0	75
      张三	  一班	86	 87.0	93
      李四	  二班	93	 92.0	81
      朱五	  二班	95	 99.0	60
      
      df.loc[['赵一','李四']]
      		班级	 语文	 数学	  英语
      姓名
      赵一	  一班	98	 96.0	97
      李四	  二班	93	 92.0	81
      
      df.iloc[[0,3]]
      		班级	 语文	 数学	  英语
      姓名
      赵一	  一班	98	 96.0	97
      李四	  二班	93	 92.0	81
      

      调用set_index()方法,我们将数据框中的“姓名“列设置为新的索引。我们既可以用loc传入标签索引的方式,获取这两位同学的数据信息,也可以用iloc传入位置索引的方式获取信息

  • 按条件筛选,有时候我们想要筛选出符合某些条件的数据,提供了**query()isin()between()**

    • 筛选数学成绩在95分以上的同学

      df[df['数学']>95]
      
    • 筛选语文和数学成绩都在90分以上的同学

      df.query("语文>90 & 数学>90")
      
    • 筛选语文成绩是88或95的同学

      df[df['语文'].isin(['88','95'])]
      
    • 筛选数学成绩在85到95之间的同学

      df[df['数学'].between(85,95)]		###不包含边界值85和95
      
数据运算
方法 作用 方法 作用
sum() 求和 abs() 求绝对值
count() 计数 mod() 求余数
mean() 求均值 value_counts() 求每个值出现的个数
max() 求最大值 prod() 求连乘积
min() 求最小值 argmax() 求最大值的索引值
mode() 求众数 idxmax() 求最大值的索引值
var() 求方差 argmin() 求最小值的索引值
std() 求标准差 idxmin() 求最小值的索引值
median() 求中位数 unique() 去重(唯一值)
  • 计算每个人的总成绩

    df['总分'] = df['语文'] + df['数学'] + df['英语']
    df
    
    	姓名	  班级	语文	 数学	 英语	  总分
    0   赵一	  一班	 98	  96.0	 97	  291.0	
    1   王二	  一班	 88	  90.0	 75	  253.0
    2   张三	  一班	 86	  87.0	 93	  266.0
    3   李四	  二班	 93	  92.0	 81	  266.0
    4   朱五	  二班	 95	  99.0	 60	  254.0
    
  • 如果想计算出每个班级的总人数,应该怎么做

    df['班级'].value_counts()
    一班	3
    二班	2
    Name: 班级, dtype:int64
    
  • 计算出每个人的平均分,并保留两位小数

    df['平均分']=df['总分'].apply(lambda x: round(x/3,2))
    df
    	姓名	  班级	语文	 数学	 英语	  总分	  平均分
    0   赵一	  一班	 98	  96.0	 97	  291.0		97.00
    1   王二	  一班	 88	  90.0	 75	  253.0	    84.33
    2   张三	  一班	 86	  87.0	 93	  266.0		88.67
    3   李四	  二班	 93	  92.0	 81	  266.0		88.67
    4   朱五	  二班	 95	  99.0	 60	  254.0		84.67
    

    apply()将”总分“这一列的每个元素,都除以3且结果保留两位小数。

    相当于

    a=[1,2,3,4,5]
    c=list(map(lambda x:x-1,a))
    print(c)
    
    [0, 1, 2, 3, 4]
    
  • 数据排序与排名

    • 数据排序:sort_value()方法可以实现

      DataFrame.sort_value(by,ascending,inplace)
      by:列名(字符/字符列表)
      ascending:是否升序排序,默认为升序:True
      inplace:是否修改原DataFrame
      
    • 按照总分降序排序

      df.sort_values(by = ["总分"],ascending=False,inplace=True)
      df
      
      	姓名	  班级	语文	 数学	 英语	  总分	  平均分
      0   赵一	  一班	 98	  96.0	 97	  291.0		97.00
      2   张三	  一班	 86	  87.0	 93	  266.0		88.67
      3   李四	  二班	 93	  92.0	 81	  266.0		88.67
      4   朱五	  二班	 95	  99.0	 60	  254.0		84.67
      1   王二	  一班	 88	  90.0	 75	  253.0	    84.33
      
      ###如果总分相同,再按英语来排序
      
      df.sort_values(by = ["总分","英语"],ascending=[False,True],inplace=True)
      df
      
      	姓名	  班级	语文	 数学	 英语	  总分	  平均分
      0   赵一	  一班	 98	  96.0	 97	  291.0		97.00
      3   李四	  二班	 93	  92.0	 81	  266.0		88.67
      2   张三	  一班	 86	  87.0	 93	  266.0		88.67
      4   朱五	  二班	 95	  99.0	 60	  254.0		84.67
      1   王二	  一班	 88	  90.0	 75	  253.0	    84.33
      
    • 数据排名

      • 当我们对数据完成排序后,就可以进行数据排名了。调用rank()方法可以实现。

        DataFrame.rank(method,ascending)
        method:排序方式
        ascending:是否升序排序,默认为True
        
      • method有5个常用选项

        • first

          姓名 总分 排名
          赵一 291 1
          张三 266 2
          李四 266 3
          朱五 254 4
          王二 253 5
        • average

          姓名 总分 排名
          赵一 291 1
          张三 266 2.5
          李四 266 2.5
          朱五 254 4
          王二 253 5
        • min

          姓名 总分 排名
          赵一 291 1
          张三 266 2
          李四 266 2
          朱五 254 4
          王二 253 5
        • max

          姓名 总分 排名
          赵一 291 1
          张三 266 3
          李四 266 3
          朱五 254 4
          王二 253 5
        • dense

          姓名 总分 排名
          赵一 291 1
          张三 266 2
          李四 266 2
          朱五 254 3
          王二 253 4
    • 按照总分来排名

      df['排名'] = df['总分'].rank(method='dense',ascending=False).astype('int')
      df
      
      	姓名	  班级	语文	 数学	 英语	  总分	  平均分	排名
      0   赵一	  一班	 98	  96.0	 97	  291.0		97.00	  1
      2   张三	  一班	 86	  87.0	 93	  266.0		88.67	  2
      3   李四	  二班	 93	  92.0	 81	  266.0		88.67	  2
      4   朱五	  二班	 95	  99.0	 60	  254.0		84.67	  3
      1   王二	  一班	 88	  90.0	 75	  253.0	    84.33	  4
      

      由于这里返回的排名值是一个浮点型,因此需要调用astype()方法实现数据类型转换

  • 数据合并与连接:用于实现对多表的操作

    • 数据合并:将同种性质表的不同部分合并在一起,一般不需要考虑公共列

      • 分为横向合并和纵向合并两种方式。使用concat()方法

        df
        	a	b	c
        0	10 	20	30
        1	40	50	60
        2	70	80	90
        
        df2
        	d
        0	35
        1	65
        2	95
        
        ###横向合并
        df_concat=pd.concat([df,df2],axis=1)
        df_concat
        	a	b	c	d
        0	10 	20	30	35
        1	40	50	60	65
        2	70	80	90	95
        
        df3
        	a	b	c
        0	110	120	130
        
        ###纵向合并,使用reset_index()可以帮助我们重置合并后的索引。不然就是 0 1 2 0
        df_concat=pd.concat([df,df3],axis=0).reset_index(drop=True)
        df_concat
        	a	b	c
        0	10 	20	30
        1	40	50	60
        2	70	80	90
        3	110	120	130
        
      • 如果想要加入学生信息表的数据

        df3 = pd.read_excel("学生信息表.xlsx")
        df3
        	姓名	性别	住址
        0	王二	男	朝阳
        1	李四	女	朝阳
        2	朱五	男	海淀
        3	黄七	男	海淀
        4	赵一	女	朝阳
        5	马六	女	海淀
        6	张三	男	海淀
        
        pd.concat([df_concat,df3],axis=1)
        	姓名	  班级	语文	 数学	 英语	 姓名	性别	住址
        0   赵一	  一班	 98	  96.0	 97	 王二	 男	 朝阳
        1   王二	  一班	 88	  90.0	 75	 李四	 女	 朝阳
        2   张三	  一班	 86	  87.0	 93	 朱五	 男	 海淀
        3   李四	  二班	 93	  92.0	 81	 黄七	 男	 海淀
        4   朱五	  二班	 95	  99.0	 60	 赵一	 女	 朝阳
        5	马六	  三班	 86	  90	 89	 马六	 女	 海淀
        6	黄七	  三班	 96	  88	 91	 张三	 男	 海淀
        
        由于concat()方法合并数据依赖索引,当两表的数据顺序不一致时,就会产生这类错误,姓名对不上。
        要想规避,以姓名为连接键
        
    • 数据连接:将不同性质表连接在一起,一般需要考虑公共列

      • 调用merge()方法实现数据连接

        pd.merge(left,right,how,on)
        
        left:左侧DataFrame对象
        right:右侧DataFrame对象
        how:数据合并的方式
        on:连接键
        
      • 两个数据框DataFrame想要进行数据连接,需要依赖某个“公共列”作为连接键,数据连接后的结果受参数how的影响

        • how=“left”:左表中的数据都会展示出来,右表会根据连接键将数据连接到左表上,对于不符合条件的数据用NaN补充(左连接)
        • how=“right”:右表中的数据都会展示出来,左表会根据连接键将数据连接到左表上,对于不符合条件的数据用NaN补充(右连接)
        • how=“inner”:参数的默认值,显示左表和右表中连接键都存在的数据(内连接)
        • how=“outer”:保留两个表的所有信息(全连接)
        df
        	a	b	c
        0	10	20	30
        1	40	50	60
        2	70	80	90
        
        df2
        	a	d
        0	10	35
        1	40	65
        2	75	95
        
        pd.merge(df,df2,how='left',on='a')
        	a	b	c	d
        0	10	20	30	35	
        1	40	50	60	65
        2	70	80	90	NaN
        
        pd.merge(df,df2,how='right',on='a')
        	a	b	c	d
        0	10	20	30	35	
        1	40	50	60	65
        2	75	NaN	NaN	95
        
        pd.merge(df,df2,how='inner',on='a')
        	a	b	c	d
        0	10	20	30	35	
        1	40	50	60	65
        
        pd.merge(df,df2,how='outer',on='a')
        	a	b	c	d
        0	10	20	30	35	
        1	40	50	60	65
        2	70	80	90	NaN
        3	75	NaN	NaN	95
        
  • 数据分组与透视表

    • 通过合并和连接得到的大表,一般用于“数据分组”和“数据透视表”的计算

      DataFrame.groupby(by).聚合函数
      by:分组依据
      
      
    • 一般分组和聚合是搭配使用的,分组后调用聚合函数完成聚合操作

      函数 作用 函数 作用
      sum() 求和 median() 求中位数
      count() 计数 var() 求方差
      mean() 求平均值 std() 求标准差
      max() 求最大值 describe() 计算描述性统计量
      min() 求最小值 first 第一次出现的值
      mode() 求众数 last 最后一次出现的值
    • 以班级分组,计算每个班级的学生数量

      df_merge = pd.merge(df_concat,df3,how='inner',on='姓名')
      df_merge
      	姓名	  班级	语文	 数学	 英语 性别	住址
      0   赵一	  一班	 98	  96.0	 97  男	 朝阳
      1   王二	  一班	 88	  90.0	 75  女	 朝阳
      2   张三	  一班	 86	  87.0	 93  男	 海淀
      3   李四	  二班	 93	  92.0	 81  男	 海淀
      4   朱五	  二班	 95	  99.0	 60  女	 朝阳
      5	马六	  三班	 86	  90	 89  女	 海淀
      6	黄七	  三班	 96	  88	 91  男	 海淀
      
      df_merge.groupby("班级").count()
      
      		姓名	语文	数学	英语	性别	住址
      班级
      一班		3	 3	  3		3	 3	   3
      二班		2	 2	  2		2	 2	   2
      三班		2	 2	  2		2	 2	   2
      
      df_merge.groupby("班级")['姓名'].count()
      班级
      一班		3	
      二班		2	
      三班		2
      Name:姓名,dtype:int64
      

      调用groupby()方法并搭配聚合函数count(),按照班级这列进行分组并对其他列进行计数,统计出每个班级的学生数量,实际上只需要对姓名这列计数就够了。

    • 以班级、住址分组

      df_merge.groupby(['班级','住址'])['姓名'].count()
      
      班级	 住址
      一班	 朝阳	 2
      	   海淀  1
      二班	 朝阳	 1
      	   海淀  1
      三班	 海淀  2
      Name:姓名,dtype:int64
      
    • 以班级分组,计算每个班语文成绩最高的分数

      df_merge.group("班级")['语文'].max()
      
      班级
      一班	98
      二班	96
      三班	95
      Name:语文,dtype:int64
      
  • 数据透视表:pivot_table()可以实现数据透视表

    参数 作用
    data 相当于Excel中的“选中数据源”
    index 相当于数据透视表字段中的行
    columns 相当于数据透视表字段中的列
    values 相当于数据透视表字段中的值
    aggfunc 相当于计算类型
    margins 相当于结果中的总计
    margins_name 相当于修改总计名
    fill_value 将缺失值用某个指定值填充
    • 以住址为行,班级为列,计算每个班级的学生数量,并统计他们的合计值

      pd.pivot_table(
      	df_merge,values="姓名",
      		columns="班级",index="住址",
      		aggfunc="count",fill_value=0,
      		margins_name='合计',margins=True
      )
      
      
      班级	一班	二班	三班	合计
      住址
      朝阳	 2	  1		0	  3	
      海淀	 1	  1		2	  4
      合计	 3	  2	    2	  7
      
  • Excel拆分与合并

    • 按条件将Excel文件拆分到不同的工作簿

      import pandas as pd
      df = pd.read_excel("三年级总成绩单.xlsx")
      
      for i in df['班级'].unique():
      	df[df['班级']==i].to_excel(f"{i}.xlsx",index=False)
      
    • 按条件将Excel拆分到不同的工作表

      import pandas as pd
      df = pd.read_excel("三年级总成绩单.xlsx")
      
      for i in df['班级'].unique():
      	df[df['班级']==i].to_excel(
      			"三年级总成绩单.xlsx",index=False,sheet_name=f"{i}"
      		)
      

      但是执行后发现每次生成的工作表都会覆盖前一个,最终只剩下一个表,用这个方法实现

      import pandas as pd
      df = pd.read_excel('三年级总成绩单.xlsx')
      
      writer = pd.ExcekWriter("三年级总成绩单.xlsx")
      df.to_excel(writer,sheet_name='总成绩',index=False)
      
      for j in df['班级'].unique():
      	df[df['班级']==j].to_excel(writer,sheet_name=j,index=False)
      

      ExcelWriter()方法,他会帮助我们建立一个空的容器对象writer

  • 批量将不同的工作表合并到一个excel文件

    import pandas as pd
    
    sheet_names = pd.ExcelFile("三年级分班成绩单.xlsx").sheet_names
    
    df_all = pd.DataFrame()
    
    for i in sheet_names:
    	df = pd.read_excel("三年级分班成绩单.xlsx",sheet_name=i)
    	df_all = df_all.append(df)
    
    df_all.to_excel(
    	'三年级分班成绩单.xlsx',sheet_name='总成绩'
    )
    

    ExcelFile()会得到一个ExcelFile对象。该对象有一个很好用的sheet_names属性,它能够获取当前表格中所有工作表的名称,并以一个列表返回

你可能感兴趣的:(pandas,python,数据分析)