Pandas 的算术运算
1. 前言
上一节我们学习了 Pandas 对重复数据的处理,主要对重复数据的检测和删除重复数据。除了对数据的单独处理操作,数据之间的运算处理也是很有必要的,那 Pandas 中是否可以开展数据之间的算术运算呢?
Pandas 库为方便数据处理,提供了强大而简洁的算术运算操作,封装了很多算术运算的函数供使用,本节课我们将学习 Pnadas 库中提供的四种算术运算操作函数,包括 add (),sub (),div (),mul () 操作,因为 Series 和 DataFrame 之间的运算比较有代表性,针对每一个算术运算我们将以 Series 和 DataFrame 进行运算的实例进行讲解。
2. 概述
Pandas 库中的算术运算是数据集之间,根据索引进行运算的,如果存在不同的索引对,运算的结果是相同索引数据和不同索引数据的并集,并且用 NaN 填充运算结果。
当进行对应索引列之间的加减乘除运算时,要注意对应索引列之间的类型是否相同,如果不同类型进行运算时会报类型转换错误,同时,要考虑到该类型是否能进行某种算术运算,比如字符串之间的加法运算是可以的,但是字符串之间是不存在减法、乘法和除法运算的,否则会报错。
在正式讲解各算术运算之前,我们先将 DataFrame 数据对象,通过 Excel 数据解析的方式进行创建,针对 Series 对象,在每次操作时,根据需要我们单独再创建。
# 导入pandas包
import pandas as pd
data_path="C:/Users/13965/Documents/myFuture/IMOOC/pandasCourse-progress/data_source/第13小节/execl数据demo.xlsx"
# 解析数据
data = pd.read_excel(data_path)
print(data)
# --- DataFrame数据解析结果 ---
编程语言 推出时间 价格 主要创始人
0 java 1995年 45.6 James Gosling
1 python 1991年 67.0 Guido van Rossum
2 C 1972年 33.9 Dennis MacAlistair Ritchie
3 js 1995年 59.5 Brendan Eich
4 php 2012年 69.9 Rasmus Lerdorf
5 C++ 1983年 75.0 Bjarne Stroustrup
3. add () 加法运算
add () 函数根据索引值,对相同索引的数据进行加法运算,注意字符串的加法是拼接操作。
# 创建 Series 对象
new_series = pd.Series(["11","22",33,"44"], index=['编程语言','推出时间','价格','last'])
print(new_series)
# --- 输出结果 ---
编程语言 11
推出时间 22
价格 33
last 44
dtype: object
# data 为从 Excel 解析出的 DataFrame 对象
# 通过 add 函数进行加运算
new_result=data.add(new_series)
print(new_result)
# --- 输出结果 ---
last 主要创始人 价格 推出时间 编程语言
0 NaN NaN 78.6 1995年22 java11
1 NaN NaN 100 1991年22 python11
2 NaN NaN 66.9 1972年22 C11
3 NaN NaN 92.5 1995年22 js11
4 NaN NaN 102.9 2012年22 php11
5 NaN NaN 108 1983年22 C++11
输出解析:new_series 对象中的 “last” 索引和 data 对象中 “主要创始人” 索引,他们之间不存在对应关系,而其他的索引是一一对应的,因此输出结果其他的列均做了加法运算 (字符串是拼接,数值是相加),而这两列则单独加入到结果集中,并且用 NaN 进行填充。
如果我们的 Series 对象中的 “价格” 是字符型,在和 DataFrame 对象运算过程中就会报类型不匹配的错误。
# 创建 Series 对象
new_series = pd.Series(["11","22","33","44"], index=['编程语言','推出时间','价格','last'])
print(new_series)
# --- 输出结果 ---
编程语言 11
推出时间 22
价格 33
last 44
dtype: object
# data 为从 Excel 解析出的 DataFrame 对象
# 通过 add 函数进行加运算
new_result=data.add(new_series)
print(new_result)
# --- 输出结果 ---
……
TypeError: unsupported operand type(s) for +: 'float' and 'str'
输出解析:因为我们的操作是在 data 数据集中加上 new_series 数据集,在 Pandas 中 str 类型加上任何类型相当于是字符串的拼接操作,而 int/float 类型值加上字符串,Pandas 不支持该算术运算,因此会报错。
4. sub () 减法运算
sub () 函数用于数据集之间对应索引的减法操作,该操作不同于加法操作,字符操作是不存在减法操作的,算术上的减法只用于数值类型的数据运算,包括整形、浮点型等。
# 创建 Series 对象
new_series = pd.Series(['11',33], index=['推出时间','价格'])
print(new_series)
# --- 输出结果 ---
推出时间 11
价格 33
dtype: object
# data 为从 Excel 解析出的 DataFrame 对象
# 通过 sub 函数进行减法运算
new_result=data.sub(new_series)
print(new_result)
# --- 输出结果 ---
……
TypeError: unsupported operand type(s) for -: 'float' and 'str'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
输出解析:因为 pandas 中的 sub () 减法操作函数只在数值类型的数据之间有效,因此在 数值和字符串型,以及字符串与字符串之间进行 sub () 操作都会报错。
下面我们只对两个数据集的价格索引了列进行 sub () 操作。
# 创建 Series 对象
new_series = pd.Series([33], index=['价格'])
print(new_series)
# --- 输出结果 ---
价格 33
dtype: int64
# data 为从 Excel 解析出的 DataFrame 对象
# 通过 sub 函数进行减法运算
new_result=data.sub(new_series)
print(new_result)
# --- 输出结果 ---
主要创始人 价格 推出时间 编程语言
0 NaN 12.6 NaN NaN
1 NaN 34.0 NaN NaN
2 NaN 0.9 NaN NaN
3 NaN 26.5 NaN NaN
4 NaN 36.9 NaN NaN
5 NaN 42.0 NaN NaN
输出解析:这里我们对两个数据集的价格列进行了相减操作,可以看到价格列的数据均减去了 33。
5. mul () 乘法运算
mul () 操作是两个数据集对应索引列的数据进行乘法运算,该函数同样只适用于两个数值数据的运算,字符串之间,字符串与数值之间进行乘法运算均会报错。
# 创建 Series 对象
new_series = pd.Series([3], index=['价格'])
print(new_series)
# --- 输出结果 ---
价格 3
dtype: int64
# data 为从 Excel 解析出的 DataFrame 对象
# 通过 mul 函数进行乘法运算
new_result=data.mul(new_series)
print(new_result)
# --- 输出结果 ---
主要创始人 价格 推出时间 编程语言
0 NaN 136.8 NaN NaN
1 NaN 201.0 NaN NaN
2 NaN 101.7 NaN NaN
3 NaN 178.5 NaN NaN
4 NaN 209.7 NaN NaN
5 NaN 225.0 NaN NaN
输出解析:通过乘法操作函数对两个数据集的价格列进行操作,可以看到输出结果中的价格均变为了以前的三倍,其他列以 NaN 进行填充。
6. div () 除法运算
div () 函数用于两个数据集对应索引列的数据进行除法运算,该函数同样只适用数值型数据之间的运算,并且除数不能为 0 ,否则会报错。
# 创建 Series 对象
new_series = pd.Series([3,"fill"], index=['价格',"add_column"])
print(new_series)
# --- 输出结果 ---
价格 3
add_column fill
dtype: object
# data 为从 Excel 解析出的 DataFrame 对象
# 通过 div 函数进行除法运算,除数不能为0
new_result=data.div(new_series)
print(new_result)
# --- 输出结果 ---
add_column 主要创始人 价格 推出时间 编程语言
0 NaN NaN 15.2 NaN NaN
1 NaN NaN 22.3333 NaN NaN
2 NaN NaN 11.3 NaN NaN
3 NaN NaN 19.8333 NaN NaN
4 NaN NaN 23.3 NaN NaN
5 NaN NaN 25 NaN NaN
输出解析:通过 div () 函数进行两个数据集价格列的除法运算,可以看到输出结果原 data 集中的价格列数据均是除以 3 的结果,而其他的数列并入到结果集合中,并以 NaN 进行填充。
下面是除数为 0 时出现的错误结果:
# 创建 Series 对象
new_series = pd.Series([0,"fill"], index=['价格',"add_column"])
print(new_series)
# --- 输出结果 ---
价格 0
add_column fill
dtype: object
# data 为从 Excel 解析出的 DataFrame 对象
# 通过 div 函数进行除法运算,除数不能为0
new_result=data.div(new_series)
print(new_result)
# --- 输出结果 ---
……
ZeroDivisionError: float division by zero
3. 小结
本节课程我们主要学习了 Pandas 中数据集之间进行的算术运算操作,主要讲解了加、减、乘、除四种操作,算术运算并不是针对字符串类型的数据(在字符串之间的加法操作相当于是进行拼接操作),而是专门用来处理数值型数据的,因此对于不同的操作需要,要清晰的知道应该使用哪种操作函数去实现。本节课程的重点如下:
- Pandas 库算术运算加减乘除四种操作对应的操作函数的使用;
- Pandas 库算术运算函数使用时常见的错误原因;