Pandas通用函数和运算

Pandas继承了Numpy的运算功能,可以快速对每个元素进行运算,即包括基本运算(加减乘除等),也包括复杂运算(三角函数、指数函数和对数函数等)。

通用函数使用

apply和applymap

apply(func,axis=0,broadcast=None,raw=False,reduce=None,result_type=None,args=(),**kwds,)

applymap(func)
In [4]: frame = pd.DataFrame(np.random.randn(4,3),columns=list('bde'),
                             index=['Utah','Ohio','Texas','Oregon'])

In [5]: frame
Out[5]:
               b         d         e
Utah    0.471961 -0.399978 -0.874515
Ohio   -0.975614 -0.521370 -0.760090
Texas  -1.117619 -1.179684 -1.067536
Oregon  0.874380 -1.233453 -1.165621

#创建一个匿名函数:最大值-最小值
In [7]: f = lambda x: x.max()-x.min()

# 默认axis = 0                                                                           
In [8]: frame.apply(f)  
Out[8]:
b    1.991999
d    0.833475
e    0.405531
dtype: float64

In [9]: frame.apply(f,axis=1)
Out[9]:
Utah      1.346476
Ohio      0.454245
Texas     0.112147
Oregon    2.107833
dtype: float64

#定义一个提取最小值和最大值的函数                                   
In [10]: def f(x):
    ...:     return pd.Series([x.min(),x.max()],index=['min','max'])


In [11]: frame.apply(f)
Out[11]:
            b         d         e
min -1.117619 -1.233453 -1.165621
max  0.874380 -0.399978 -0.760090

In [12]: format = lambda x : '%.2f'%x

In [13]: frame.applymap(format)
Out[13]:
            b      d      e
Utah     0.47  -0.40  -0.87
Ohio    -0.98  -0.52  -0.76
Texas   -1.12  -1.18  -1.07
Oregon   0.87  -1.23  -1.17

In [14]: frame['e'].map(format)
Out[14]:
Utah      -0.87
Ohio      -0.76
Texas     -1.07
Oregon    -1.17
Name: e, dtype: object

一元运算

Pandas在进行一元运算(函数等),输出的结果会保留索引和列标签。

Series

In [1]: import pandas as pd
In [2]: import numpy as np

#确定一个随机种子
In [3]: rng = np.random.RandomState(42)
    
In [4]: ser = pd.Series(rng.randint(0,10,4))

In [5]: ser
Out[5]:
0    6
1    3
2    7
3    4
dtype: int32

In [6]: np.exp(ser)
Out[6]:
0     403.428793
1      20.085537
2    1096.633158
3      54.598150
dtype: float64

DataFrame

In [7]: df = pd.DataFrame(rng.randint(0,10,(3,4)),columns=list('ABCD'))

In [8]: df
Out[8]:
   A  B  C  D
0  6  9  2  6
1  7  4  3  7
2  7  2  5  4

In [9]: np.sin(df*np.pi/4)
Out[9]:
          A             B         C             D
0 -1.000000  7.071068e-01  1.000000 -1.000000e+00
1 -0.707107  1.224647e-16  0.707107 -7.071068e-01
2 -0.707107  1.000000e+00 -0.707107  1.224647e-16

二元运算

进行二元运算时(如加法和减法等),Pandas会在计算过程中自动对齐两个对象的索引。在直接应用Python运算符时,在缺失位置会用NaN填充,这种方法是Python的内置集合运算规则;用Pandas方法(可设置填充值或填充方法)代替运算符,可以避免NaN产生。

Python运算符 Pandas方法
+ add(),radd()
- sub(),rsub()
* mul(),rmul()
/ div(),rdiv()
// floordiv(),rfloordiv()
% mod()
** pow(),rpow()

Series

In [10]: A = pd.Series([2,4,6],index=[0,1,2])

In [11]: B = pd.Series([1,3,5],index=[1,2,3])

#索引不匹配时以NaN填充
In [12]: A + B
Out[12]:
0    NaN
1    5.0
2    9.0
3    NaN
dtype: float64

In [13]: A.add(B)
Out[13]:
0    NaN
1    5.0
2    9.0
3    NaN
dtype: float64

#fill_value表示不匹配时缺失值以0填充后再运算
In [14]: A.add(B,fill_value=0)
Out[14]:
0    2.0
1    5.0
2    9.0
3    5.0
dtype: float64

DataFrame

In [15]: C = pd.DataFrame(rng.randint(0,20,(2,2)))
In [16]: D = pd.DataFrame(rng.randint(0,10,(3,3)))

In [17]: C
Out[17]:
   0   1
0  1  11
1  5   1

In [18]: D
Out[18]:
   0  1  2
0  4  0  9
1  5  8  0
2  9  2  6

In [19]: C.columns = list('AB')

In [20]: C
Out[20]:
   A   B
0  1  11
1  5   1

In [21]: D.columns = list('ABC')

In [21]: D
Out[21]:
   A  B  C
0  4  0  9
1  5  8  0
2  9  2  6

#索引不匹配时以NaN填充
In [23]: C + D
Out[23]:
      A     B   C
0   5.0  11.0 NaN
1  10.0   9.0 NaN
2   NaN   NaN NaN

In [24]: C.stack()
Out[24]:
0  A     1
   B    11
1  A     5
   B     1
dtype: int32

In [25]: fill = C.stack().mean()

In [26]: fill
Out[26]: 4.5

#fill_value表示不匹配时缺失值以4.5填充后再运算
In [27]: C.add(D,fill_value=fill)
Out[27]:
      A     B     C
0   5.0  11.0  13.5
1  10.0   9.0   4.5
2  13.5   6.5  10.5

Series与DataFrame的结合运算

Series与DataFrame结合运算,会根据Numpy的广播规则对Series进行处理后,再与DataFrame运算。

In [36]: A = rng.randint(10,size=(3,4))

In [37]: A
Out[37]:
array([[3, 8, 2, 4],
       [2, 6, 4, 8],
       [6, 1, 3, 8]])

In [38]: df = pd.DataFrame(A,columns = list('ABCD'))

In [39]: ser = pd.Series(A[0],index=list('ABCD'))

In [40]: df
Out[40]:
   A  B  C  D
0  3  8  2  4
1  2  6  4  8
2  6  1  3  8

In [41]: ser
Out[41]:
A    3
B    8
C    2
D    4
dtype: int32

#ser经过广播后变成3*4的数组,与df的3*4数组以列标签对齐进行运算
In [42]: df - ser
Out[42]:
   A  B  C  D
0  0  0  0  0
1 -1 -2  2  4
2  3 -7  1  4

In [43]: ser2 = df['B']

In [44]: ser2
Out[44]:
0    8
1    6
2    1
Name: B, dtype: int32

#ser2经过广播后变成3*4的数组,与df的3*4数组以行索引对齐进行运算
In [46]: df.subtract(ser2,axis=0)
Out[46]:
   A  B  C  D
0 -5  0 -6 -4
1 -4  0 -2  2
2  5  0  2  7
posted @ 2022-01-24 16:28  溪奇的数据  阅读(247)  评论(0编辑  收藏  举报