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  199545.6               James Gosling
1  python  199167.0            Guido van Rossum
2       C  197233.9  Dennis MacAlistair Ritchie
3      js  199559.5                Brendan Eich
4     php  201269.9              Rasmus Lerdorf
5     C++  198375.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  199522    java11
1  NaN   NaN    100  199122  python11
2  NaN   NaN   66.9  197222       C11
3  NaN   NaN   92.5  199522      js11
4  NaN   NaN  102.9  201222     php11
5  NaN   NaN    108  198322     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 库算术运算函数使用时常见的错误原因;

图片描述