4.Pands数值运算方法

Pandas数值运算方法

Numpy相比于Python内置列表实现了元素的快速运算,在此基础上,Pandas实现了Numpy数组的显式索引

基于Pandas的显式索引给予了我们强大的数据选择能力

而Pandas是基于Numpy实现的,因此Pandas还实现了数组运算的索引保留和对齐.

对于一元运算,运算结果将保留索引和列标签,对于二元运算将会自动对齐索引

通用函数:保留索引

我们对Pandas的Series和DataFrame对象使用通用函数来进行计算(因为只有Series和DataFrame对象会储存数据)时候,Pandas会自动的保留原有的索引

例如:

array_1=np.random.randint(0,10,5)
array_2=np.random.randint(0,10,15).reshape(5,3)
Series_1=pd.Series(array_1,index=list('abcde'))
DataFrame_1=pd.DataFrame(array_2,columns=list('123'),index=list('abcde'))
print(Series_1)
print('')
print(Series_1**2)
print('\n\n')
print(DataFrame_1)
print('')
print(DataFrame_1**2)
>>>
a    1
b    0
c    6
d    3
e    2
dtype: int64

a     1
b     0
c    36
d     9
e     4
dtype: int64



   1  2  3
a  6  6  5
b  3  6  9
c  7  2  6
d  0  9  0
e  8  2  3

    1   2   3
a  36  36  25
b   9  36  81
c  49   4  36
d   0  81   0
e  64   4   9

通用函数:索引对齐

Series对象的索引对齐

当我们使用通用函数来对两个或多个Series,DataFrame对象进行运算时,Pandas会自动对齐索引来进行计算

array_1=np.random.randint(0,10,5)
array_2=np.random.randint(0,10,5)
Series_1=pd.Series(array_1,index=list('abcde'))
Series_2=pd.Series(array_2,index=list('edcba'))
print(Series_1)
print(Series_2)
print(Series_1+Series_2)
>>> 
a    4
b    5
c    4
d    9
e    2
dtype: int64
e    4
d    0
c    5
b    3
a    5
dtype: int64
a    9
b    8
c    9
d    9
e    6
dtype: int64

注意,如果两个Series具有不同的索引,结果将会如下

array_1=np.random.randint(0,10,5)
array_2=np.random.randint(0,10,5)
Series_1=pd.Series(array_1,index=list('abcde'))
Series_2=pd.Series(array_2,index=list('fdcba'))
print(Series_1)
print(Series_2)
print(Series_1+Series_2)
>>>
a    2
b    1
c    7
d    1
e    6
dtype: int64
f    0
d    4
c    0
b    5
a    9
dtype: int64
a    11.0
b     6.0
c     7.0
d     5.0
e     NaN
f     NaN
dtype: float64

参与运算的Series对象所不共有的Index会以NaN(Not a Number)填充

具体运算过程是首先将参与运算的所有Series对象或扩展至具有所有的Index,原Series对象不具有的Index扩充后其值会以NaN填充,所有的数值与NaN运算都是NaN,最后返回一个具有所有Index的Series对象

Series对象的索引对齐是通过Python内置的集合运算规则来实现的

为了避免NaN的污染效果,我们可以使用完整的通用函数,并且指定fill参数来填充NaN

array_1=np.random.randint(0,10,5)
array_2=np.random.randint(0,10,5)
Series_1=pd.Series(array_1,index=list('abcde'))
Series_2=pd.Series(array_2,index=list('fdcba'))
print(Series_1)
print(Series_2)
print(Series_1.add(Series_2,fill_value=0))
>>>
a    9
b    0
c    2
d    1
e    4
dtype: int64
f    3
d    5
c    1
b    6
a    1
dtype: int64
a    10.0
b     6.0
c     3.0
d     6.0
e     4.0
f     3.0
dtype: float64

除此以外,我们还可以找出NaN的位置,然后使用Numpy花哨的索引来让所有的NaN置为0,具体如何处理将在后面讲解

DataFrame对象的索引对齐

与Series对象类似,DataFrame对象的索引对齐几乎一样

array_1=np.random.randint(0,10,(3,4))
array_2=np.random.randint(0,10,(3,4))
DataFrame_1=pd.DataFrame(array_1,columns=list('abcd'),index=list('abc'))
DataFrame_2=pd.DataFrame(array_2,columns=list('abcd'),index=list('cba'))
print(DataFrame_1)
print('')
print(DataFrame_2)
print('')
print(DataFrame_1.add(DataFrame_2))
>>>
   a  b  c  d
a  9  8  3  5
b  2  2  4  1
c  2  4  9  8

   a  b  c  d
c  0  0  1  7
b  8  4  0  5
a  6  6  5  3

    a   b   c   d
a  15  14   8   8
b  10   6   4   6
c   2   4  10  15

对于缺失的行或者列,都会以NaN填充

array_1=np.random.randint(0,10,(3,4))
array_2=np.random.randint(0,10,(3,4))
array_3=np.random.randint(0,10,(3,4))
DataFrame_1=pd.DataFrame(array_1,columns=list('abcd'),index=list('abc'))
DataFrame_2=pd.DataFrame(array_2,columns=list('abcd'),index=list('abd'))
DataFrame_3=pd.DataFrame(array_3,columns=list('abce'),index=list('abc'))
print(DataFrame_1)
print('')
print(DataFrame_2)
print('')
print(DataFrame_3)
print('')
print(DataFrame_1.add(DataFrame_2))
print('')
print(DataFrame_1.add(DataFrame_3))
>>>
   a  b  c  d
a  1  4  4  2
b  5  0  5  8
c  4  1  4  3

   a  b  c  d
a  8  6  4  4
b  2  6  5  4
d  5  6  0  5

   a  b  c  e
a  3  1  9  0
b  1  9  8  4
c  4  4  6  4

     a     b     c     d
a  9.0  10.0   8.0   6.0
b  7.0   6.0  10.0  12.0
c  NaN   NaN   NaN   NaN
d  NaN   NaN   NaN   NaN

   a  b   c   d   e
a  4  5  13 NaN NaN
b  6  9  13 NaN NaN
c  8  5  10 NaN NaN

同样我们可以调用DataFrame对象内置的add通用函数,调用fill_value属性来避免NaN的污染

array_1=np.random.randint(0,10,(3,4))
array_2=np.random.randint(0,10,(3,4))
array_3=np.random.randint(0,10,(3,4))
DataFrame_1=pd.DataFrame(array_1,columns=list('abcd'),index=list('abc'))
DataFrame_2=pd.DataFrame(array_2,columns=list('abcd'),index=list('abd'))
DataFrame_3=pd.DataFrame(array_3,columns=list('abce'),index=list('abc'))
print(DataFrame_1)
print('')
print(DataFrame_2)
print('')
print(DataFrame_3)
print('')
print(DataFrame_1.add(DataFrame_2,fill_value=0))
print('')
print(DataFrame_1.add(DataFrame_3,fill_value=0))
>>>
  a  b  c  d
a  0  3  9  0
b  3  0  9  5
c  0  0  6  9

   a  b  c  d
a  4  2  0  0
b  9  5  4  5
d  5  7  8  7

   a  b  c  e
a  5  3  1  3
b  2  0  1  6
c  3  0  3  8

      a    b     c     d
a   4.0  5.0   9.0   0.0
b  12.0  5.0  13.0  10.0
c   0.0  0.0   6.0   9.0
d   5.0  7.0   8.0   7.0

   a  b   c    d    e
a  5  6  10  0.0  3.0
b  5  0  10  5.0  6.0
c  3  0   9  9.0  8.0

DataFrame对象与Series对象的索引对齐

同为Series或者同为DataFrame对象之间,索引无法对齐时,将会以NaN填充,但是DataFrame对象与Series对象进行运算时,却会以类似一维数组与二维数组进行广播

但是需要注意的,DataFrame对象与Series对象的索引对齐是按照列索引来进行对齐的

array_1=np.random.randint(0,10,(3,4))
array_2=np.random.randint(0,10,3)
array_3=np.random.randint(0,10,3)
DataFrame_1=pd.DataFrame(array_1,columns=list('abcd'),index=list('123'))
Series_1=pd.Series(array_2,index=list('123'))
Series_2=pd.Series(array_3,index=list('abc'))
print(DataFrame_1)
print(Series_1)
print(Series_2)
print(DataFrame_1-Series_1)
print(DataFrame_1-Series_2)
>>>
  a  b  c  d
1  0  6  9  0
2  4  2  6  4
3  0  6  2  8
1    3
2    4
3    2
dtype: int64
a    4
b    3
c    7
dtype: int64
    1   2   3   a   b   c   d
1 NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN
     a    b    c   d
1 -4.0  3.0  2.0 NaN
2  0.0 -1.0 -1.0 NaN
3 -4.0  3.0 -5.0 NaN

我们如果需要对DataFrame对象的某一行列进行运算,直接使用values属性对底层数组进行操作

注意需要对Series的底层数组升维之后进行操作

array_1=np.random.randint(0,10,(3,4))
array_2=np.random.randint(0,10,3)
DataFrame_1=pd.DataFrame(array_1,columns=list('abcd'),index=list('123'))
Series_1=pd.Series(array_2,index=list('123'))
print(DataFrame_1)
print('')
print(Series_1)
print(DataFrame_1.values-Series_1.values[:,np.newaxis])
>>>
   a  b  c  d
1  4  5  5  8
2  6  4  5  8
3  1  1  9  9

1    4
2    6
3    0
dtype: int64
[[ 0  1  1  4]
 [ 0 -2 -1  2]
 [ 1  1  9  9]]

注意,这里由于Series_1只有三个数字,因此想要能够成功广播就需要将其升维为(3,1)才能够横向广播


Pandas对象的方法

上面介绍了DataFrame对象和Series对象运算时索引对齐和索引保留

下面将介绍Python和Pandas中的方法的运算

Python运算符Pandas方法
+add()
-sub(),subtract()
*mul(),multiply()
/truediv(),div(),divide()
//follrdiv()
%mod()
**pow()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值