【基本工具】S02E09 Series与DataFrame对象的数值运算

0.本集概览

1.DataFrame和Series一元运算会作用于每一个数据元素
2.DataFrame间和Sereis间的二元运算会自动对齐索引,并进行缺失值处理
3.DataFrame和Series之间可以进行行、列两方向上的运算,同样会对齐索引

介绍完Pandas对象的构造和数据获取,这一集,我们来说说Series和DataFrame类型的数值运算。

1.一元运算作用于每一个数据元素

首先说说一元运算,由于Pandas的底层是基于NumPy实现,所以自然而言一元运算会作用于Pandas数据类型的每个数据组成元素,并且保留行、列标签索引。

我们来看两个例子,第一个是Series对象的一元数值运算:
代码片段:

import pandas as pd
import numpy as np

ser = pd.Series([2,4,6,8],
                index=['a','b','c','d'])
print(ser)
print(np.exp(ser))

运行结果:

a    2
b    4
c    6
d    8
dtype: int64

a       7.389056
b      54.598150
c     403.428793
d    2980.957987
dtype: float64

DataFrame数据对象的操作也是一样的:
代码片段:

import pandas as pd
import numpy as np

rng = np.random.RandomState(18)
df = pd.DataFrame(rng.randint(0,10,(3,4)),
                  columns=['a','b','c','d'])
print(df)
print(np.sin(df * np.pi / 4))

运行结果:

   a  b  c  d
0  3  8  5  1
1  2  2  8  8
2  2  1  5  5

          a             b             c             d
0  0.707107 -2.449294e-16 -7.071068e-01  7.071068e-01
1  1.000000  1.000000e+00 -2.449294e-16 -2.449294e-16
2  1.000000  7.071068e-01 -7.071068e-01 -7.071068e-01

提醒一句,在NumPy中使用的一元运算符,都是可以拿到Pandas数据对象中使用的。

2.二元运算

2.1.基本方法

接着说说二元运算。

在两个Series之间或两个DataFrame数据对象之间进行二元运算的时候,会自动在计算过程中对齐两个对象的索引,如果一个索引仅在一个对象中出现,那么另一个对象的索引空缺处会进行空值处理。
代码片段:

import pandas as pd
import numpy as np

ser1 = pd.Series({'a':10,'b':20,'d':40})
ser2 = pd.Series({'b':2,'c':3,'d':4})
print(ser1 / ser2)

运算结果:

a     NaN
b    10.0
c     NaN
d    10.0
dtype: float64

从结果中我们很容易发现,结果中的索引是两个输入数组索引的并集,对于参与二元运算的两个Series,缺失位置的数据,Pandas默认都会用NaN填充,并且有NaN参与的运算,其结果也是NaN。

2.2.缺失值的处理

不过我们可以打破这种默认,例如,我们可以设置参与运算的Series,其索引缺失位置的数据为0。
代码片段:

import pandas as pd
import numpy as np

ser1 = pd.Series({'a':10,'b':20,'d':40})
ser2 = pd.Series({'b':2,'c':3,'d':4})
print(ser1.add(ser2, fill_value=0))

运算结果:

a    10.0
b    22.0
c     3.0
d    44.0
dtype: float64

DataFrame间的运算,当然也同样会进行索引对齐:
代码片段:

import pandas as pd
import numpy as np

rng = np.random.RandomState(10)
A = pd.DataFrame(rng.randint(0, 20, (2, 2)),
                 columns=['A', 'B'])
B = pd.DataFrame(rng.randint(0, 10, (3, 3)),
                 columns=['B', 'C', 'A'])
print(A)
print(B)
print(A + B)

运算结果:

    A  B
0   9  4
1  15  0

   B  C  A
0  1  9  0
1  1  8  9
2  0  8  6

      A    B   C
0   9.0  5.0 NaN
1  24.0  1.0 NaN
2   NaN  NaN NaN

这里面我们要留意一点,我们看,B的列标签是B,C,A的顺序,当然这都不影响Pandas将参与二元运算的两个DataFrame进行列对齐

当然我们也可以用指定的非默认值来替换掉NaN,例如使用对象A的均值:
代码片段:

top Created with Sketch.