首页 > pandas 阅读数:24

pandas数据结构之间的运算

pandas 数据结构 Series 和 DataFrame 对象都支持 NumPy 的接口,因此,这两种数据结构都可以使用 NumPy 提供的 ufunc 函数。pandas 还提供了一些运算方法,如 mean()、std() 和 max() 等,这些函数与 NumPy 类似。此外,pandas 还提供了二元运算符对应的函数,如 add()、sub()、mul()、div() 和 mod() 等。在算术运算中,pandas 还具备按轴自动或显式数据对齐的功能。

算术和数据对齐

pandas 具有将两个数据结构索引自动对齐的功能。当参与运算的两个数据结构其索引项的顺序不一致,或者有的索引只存在于一个数据结构中时,也能实现这两个数据结构之间的运算,这称之为 pandas 的数据对齐。

【例 1】定义两个 Series 对象,分别指定两个不完全一致的标签数组,并将这两个 Series 对象进行加、减、乘、除算术运算。

其程序代码 test1.py 如下。
# -*- coding: utf-8 -*-
import numpy as np
from pandas import DataFrame,Series
print ('定义两个Series对象')
se1 = Series([2.1, 4.3, -1.6], index = ['c', 'd', 'a'])
se2 = Series(np.arange(4), index = ['a', 'b', 'c', 'd'])
print(se1,se2)
#将两个Series对象进行加、减、乘、除算术运算
se = se1+se2
print('两个Series对象相加',se)
print('两个Series对象相减',se1-se2)
print('两个Series对象相乘',se1*se2)
print('两个Series对象相除',se1/se2)

两个 Series 对象相加的结果如下。
a   -1.6
b    NaN
c    4.1
d    7.3
dtype: float64
观察输出结果可知,两个 Series 对象相加就是将两个 Series 对象中标签相同的元素相加,并输出这些标签和相加后的值。对于只有一个 Series 对象有的标签,也会出现在输出结果中,但其值为 NaN。

【例 2 】定义两个 DataFrame 对象,分别指定它们的行索引和列索引不完全一致,并将这两个 DataFrame 对象进行加、减、乘、除算术运算。

其程序代码 test2.py 如下。
# -*- coding: utf-8 -*-
import numpy as np
from pandas import DataFrame,Series
print ('定义两个DataFrame')
df1 = DataFrame(np.arange(6).reshape(2,3), columns=['a','b','c'])
df2 = DataFrame(np.arange(12).reshape(3,4),columns=['a','b','c','d'])
print('df1',df1,'\n','df2',df2)

#将两个DataFrame对象进行加、减、乘、除运算
df = df1 + df2
print('两个DataFrame对象相加','\n',df)
print('两个DataFrame对象相减','\n',df1-df2)
print('两个DataFrame对象相乘','\n',df1*df2)
print('两个DataFrame对象相除','\n',df1/df2)

两个 DataFrame 对象相加的结果如下。
定义两个DataFrame
df1         a  b  c
         0  0  1  2
         1  3  4  5
df2         a  b  c   d
         0  0  1  2   3
         1  4  5  6   7
         2  8  9  10  11
两个DataFrame对象相加
             a    b     c    d
         0 0.0  2.0   4.0  NaN
         1 7.0  9.0  11.0  NaN
         2 NaN  NaN   NaN  NaN
观察输出结果可知,两个 DataFrame 对象相加就是将两个 DataFrame 对象中行索引和列标签都相同的元素相加,并输出索引和相加后的值。对于只有一个 DataFrame 对象有的行索引和列标签,也会出现在输出结果中,但其值为 NaN。

算术运算方法

pandas 数据结构之间可以使用运算符运算,也可以使用算术运算方法来完成。pandas 提供的算术运算方法有 add()、sub()、mul()、div() 和 mod() 等函数。这些函数分别可完成加、减、乘、除和求余数的运算,函数的调用方法如下:

obj1.add(obj2)

其中,obj1 和 obj2 是 Series 或 DataFrame 对象;sub()、mul()、div() 和 mod() 等函数的调用方法与 add() 相同。

【例 3 】定义两个 DataFrame 对象,分别指定它们的行索引和列索引不完全一致,并用 add()、sub()、mul()、div() 和 mod() 等函数对这两个 DataFrame 对象进行加、减、乘、除和求余数运算。

其程序代码 test3.py 如下。
# -*- coding: utf-8 -*-
import numpy as np
from pandas import DataFrame,Series
print ('定义两个DataFrame')
df1 = DataFrame(np.arange(6).reshape(2,3), columns=['a','b','c'])
df2 = DataFrame(np.arange(12).reshape(3,4),columns=['a','b','c','d']
print('df1',df1,'\n','df2',df2)
#将两个DataFrame对象进行加、减、乘、除、求余数运算
df = df1.add(df2)
print('两个DataFrame对象相加',df)
print('两个DataFrame对象相减',df1.sub(df2))
print('两个DataFrame对象相乘',df1.mul(df2))
print('两个DataFrame对象相除',df1.div(df2))
print('两个DataFrame对象求余',df1.mod(df2))
观察该程序的输出结果,可见其运算结果与用算术运算符运算的结果是相同的。

DataFrame 与 Series 对象之间的运算

pandas 不仅可以实现相同数据结构之间的运算,而且还可以实现不同数据结构之间的运算。例如,DataFrame 与 Series 对象之间运算。

【例 4 】定义一个 Series 对象 se=Series(np.arange(4)),再定义一个 DataFrame 对象 df=DataFrame(np.arange(6).reshape(2,3),编写一个程序实现这两种不同数据结构之间的运算。

其程序代码 test4.py 如下。
# -*- coding: utf-8 -*-
import numpy as np
from pandas import DataFrame,Series
print ('定义Series对象')
se1 = Series(np.arange(4), index = ['a', 'b', 'c', 'd'])
print ('定义DataFrame对象')
df1 = DataFrame(np.arange(6).reshape(2,3), columns=['a','b','c
print('se1',se1,'\n','df1',df1)

#将Series与DataFrame对象进行加、减、乘、除运算
df = df1 + se1
print('相加',df)
print('相减',df1-se1)
print('相乘',df1*se1)
print('相除',df1/se1)

Series 与 DataFrame 对象进行加法运算的结果如下。
se1     a    0
        b    1
        c    2
        d    3
       dtype: int32
df1         a  b  c
         0  0  1  2
         1  3  4  5
相加         a  b  c   d
         0  0  2  4 NaN
         1  3  5  7 NaN
观察程序输出结果可知,Series 与 DataFrame 对象之间的运算就是将 DataFrame 对象中的所有行同时与 Series 对象进行运算,运算时是将 Series 对象的索引和 DataFrame 对象的列名称相同的元素进行运算。而 Series 对象的索引和 DataFrame 对象的列名称不匹配的索引,也会出现在输出结果中,但其值为 NaN。

因此,要实现 Series 与 DataFrame 对象之间的运算,Series 对象的索引和 DataFrame 对象的列名称一定要有相同部分,否则输出结果会全部为 NaN。