Pandas 系列文章:


专栏:

NumPy 专栏】【Pandas 专栏】【Matplotlib 专栏

推荐学习资料与网站:

NumPy 中文网】【Pandas 中文网】【Matplotlib 中文网】【NumPy、Matplotlib、Pandas 速查表


1
2
3
4
5
这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106743778
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!

【01x00】Pandas 算术运算

Pandas 继承了 NumPy 的功能,NumPy 的基本能力之一是快速对每个元素进行运算,既包括基本算术运算(加、减、乘、除),也包括更复杂的运算(三角函数、指数函数和对数函数等)。具体可以参考 NumPy 系列文章。

【01x01】使用 NumPy 通用函数

因为 Pandas 是建立在 NumPy 基础之上的,所以 NumPy 的通用函数同样适用于 Pandas 的 Series 和 DataFrame 对象,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> import pandas as pd
>>> import numpy as np
>>> rng = np.random.RandomState(42)
>>> ser = pd.Series(rng.randint(0, 10, 4))
>>> ser
0 6
1 3
2 7
3 4
dtype: int32
>>>
>>> obj = pd.DataFrame(rng.randint(0, 10, (3, 4)), columns=['A', 'B', 'C', 'D'])
>>> obj
A B C D
0 6 9 2 6
1 7 4 3 7
2 7 2 5 4

使用 NumPy 通用函数,生成的结果是另一个保留索引的 Pandas 对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> import pandas as pd
>>> import numpy as np
>>> rng = np.random.RandomState(42)
>>> ser = pd.Series(rng.randint(0, 10, 4))
>>> ser
0 6
1 3
2 7
3 4
dtype: int32
>>>
>>> np.exp(ser)
0 403.428793
1 20.085537
2 1096.633158
3 54.598150
dtype: float64
1
2
3
4
5
6
7
8
>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.DataFrame(rng.randint(0, 10, (3, 4)), columns=['A', 'B', 'C', 'D'])
>>> np.sin(obj * np.pi / 4)
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

【01x02】数据对齐

Pandas 最重要的一个功能是,它可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。自动的数据对齐操作会在不重叠的索引处引入缺失值,即 NaN,缺失值会在算术运算过程中传播。

Series 对象的数据对齐操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>>> import pandas as pd
>>> obj1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
>>> obj2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g'])
>>> obj1
a 7.3
c -2.5
d 3.4
e 1.5
dtype: float64
>>>
>>> obj2
a -2.1
c 3.6
e -1.5
f 4.0
g 3.1
dtype: float64
>>>
>>> obj1 + obj2
a 5.2
c 1.1
d NaN
e 0.0
f NaN
g NaN
dtype: float64

DataFrame 对象的数据对齐操作会同时发生在行和列上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> import pandas as pd
>>> obj1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list('bcd'), index=['Ohio', 'Texas', 'Colorado'])
>>> obj2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])
>>> obj1
b c d
Ohio 0.0 1.0 2.0
Texas 3.0 4.0 5.0
Colorado 6.0 7.0 8.0
>>>
>>> obj2
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
>>>
>>> obj1 + obj2
b c d e
Colorado NaN NaN NaN NaN
Ohio 3.0 NaN 6.0 NaN
Oregon NaN NaN NaN NaN
Texas 9.0 NaN 12.0 NaN
Utah NaN NaN NaN NaN

【01x03】DataFrame 与 Series 之间的运算

首先回忆 NumPy 中的广播(参见:《Python 数据分析三剑客之 NumPy(二):数组索引 / 切片 / 广播 / 拼接 / 分割》),跟不同维度的 NumPy 数组一样,DataFrame 和 Series 之间算术运算也是有明确规定的。首先回忆一下 NumPy 中不同维度的数组之间的运算:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> import numpy as np
>>> arr = np.arange(12.).reshape((3, 4))
>>> arr
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
>>>
>>> arr[0]
array([0., 1., 2., 3.])
>>>
>>> arr - arr[0]
array([[0., 0., 0., 0.],
[4., 4., 4., 4.],
[8., 8., 8., 8.]])

可以看到每一行都进行了减法运算,这正是 NumPy 中的广播,而 DataFrame 与 Series 之间的运算也类似,默认情况下,DataFrame 和 Series 之间的算术运算会将 Series 的索引匹配到 DataFrame 的列,然后沿着行一直向下广播:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> import numpy as np
>>> import pandas as pd
>>> frame = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'), index=['AA', 'BB', 'CC', 'DD'])
>>> frame
b d e
AA 0.0 1.0 2.0
BB 3.0 4.0 5.0
CC 6.0 7.0 8.0
DD 9.0 10.0 11.0
>>>
>>> series = frame.iloc[0]
>>> series
b 0.0
d 1.0
e 2.0
Name: AA, dtype: float64
>>>
>>> frame - series
b d e
AA 0.0 0.0 0.0
BB 3.0 3.0 3.0
CC 6.0 6.0 6.0
DD 9.0 9.0 9.0

如果某个索引值在 DataFrame 的列或 Series 的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> import numpy as np
>>> import pandas as pd
>>> frame = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'), index=['AA', 'BB', 'CC', 'DD'])
>>> frame
b d e
AA 0.0 1.0 2.0
BB 3.0 4.0 5.0
CC 6.0 7.0 8.0
DD 9.0 10.0 11.0
>>>
>>> series = pd.Series(range(3), index=['b', 'e', 'f'])
>>> series
b 0
e 1
f 2
dtype: int64
>>>
>>> frame + series
b d e f
AA 0.0 NaN 3.0 NaN
BB 3.0 NaN 6.0 NaN
CC 6.0 NaN 9.0 NaN
DD 9.0 NaN 12.0 NaN

如果希望匹配行且在列上广播,则必须使用算术运算方法,在方法中传入的轴(axis)就是希望匹配的轴。在下例中,我们的目的是匹配 DataFrame 的行索引(axis=’index’ or axis=0)并进行广播:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
>>> import numpy as np
>>> import pandas as pd
>>> frame = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'), index=['AA', 'BB', 'CC', 'DD'])
>>> frame
b d e
AA 0.0 1.0 2.0
BB 3.0 4.0 5.0
CC 6.0 7.0 8.0
DD 9.0 10.0 11.0
>>>
>>> series = frame['d']
>>> series
AA 1.0
BB 4.0
CC 7.0
DD 10.0
Name: d, dtype: float64
>>>
>>> frame.sub(series, axis='index')
b d e
AA -1.0 0.0 1.0
BB -1.0 0.0 1.0
CC -1.0 0.0 1.0
DD -1.0 0.0 1.0

【01x04】Pandas 算术方法

完整的 Pandas 算术方法见下表:

方法 副本 描述
add() radd() 加法(+)
sub()、subtract() rsub() 减法(-)
mul()、multiply() rmul() 乘法(*)
pow() rpow() 指数(**)
truediv()、div()、divide() rdiv() 除法(/)
floordiv() rfloordiv() 底除(//)
mod() rmod() 求余(%)

副本均为原方法前加了个 r,它会翻转参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> import pandas as pd
>>> obj = pd.DataFrame(np.arange(12.).reshape((3, 4)), columns=list('abcd'))
>>> obj
a b c d
0 0.0 1.0 2.0 3.0
1 4.0 5.0 6.0 7.0
2 8.0 9.0 10.0 11.0
>>>
>>> 1 / obj
a b c d
0 inf 1.000000 0.500000 0.333333
1 0.250 0.200000 0.166667 0.142857
2 0.125 0.111111 0.100000 0.090909
>>>
>>> obj.rdiv(1)
a b c d
0 inf 1.000000 0.500000 0.333333
1 0.250 0.200000 0.166667 0.142857
2 0.125 0.111111 0.100000 0.090909

1
2
3
4
5
这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106743778
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!

【02x00】处理缺失值

在现实中遇到的数据很少是干净整齐的,许多数据集都会有数据缺失的现象,缺失值主要有三种形式:null、NaN(NAN,nan) 或 NA。

【02x01】fill_value() 指定值与缺失值进行运算

使用 add, sub, div, mul 等算术方法时,通过 fill_value 指定填充值,未对齐的数据将和填充值做运算。

Series 中的应用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
>>> import pandas as pd
>>> obj1 = pd.Series([1, 2, 3, 4, 5])
>>> obj2 = pd.Series([6, 7])
>>>
>>> obj1
0 1
1 2
2 3
3 4
4 5
dtype: int64
>>>
>>> obj2
0 6
1 7
dtype: int64
>>>
>>> obj1.add(obj2)
0 7.0
1 9.0
2 NaN
3 NaN
4 NaN
dtype: float64
>>>
>>> obj1.add(obj2, fill_value=-1)
0 7.0
1 9.0
2 2.0
3 3.0
4 4.0
dtype: float64

DataFrame 中的应用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
>>> import pandas as pd
>>> import numpy as np
>>> obj1 = pd.DataFrame(np.arange(12.).reshape((3, 4)), columns=list('abcd'))
>>> obj2 = pd.DataFrame(np.arange(20.).reshape((4, 5)), columns=list('abcde'))
>>>
>>> obj2.loc[1, 'b'] = np.nan
>>>
>>> obj1
a b c d
0 0.0 1.0 2.0 3.0
1 4.0 5.0 6.0 7.0
2 8.0 9.0 10.0 11.0
>>>
>>> obj2
a b c d e
0 0.0 1.0 2.0 3.0 4.0
1 5.0 NaN 7.0 8.0 9.0
2 10.0 11.0 12.0 13.0 14.0
3 15.0 16.0 17.0 18.0 19.0
>>>
>>> obj1 + obj2
a b c d e
0 0.0 2.0 4.0 6.0 NaN
1 9.0 NaN 13.0 15.0 NaN
2 18.0 20.0 22.0 24.0 NaN
3 NaN NaN NaN NaN NaN
>>>
>>> obj1.add(obj2, fill_value=10)
a b c d e
0 0.0 2.0 4.0 6.0 14.0
1 9.0 15.0 13.0 15.0 19.0
2 18.0 20.0 22.0 24.0 24.0
3 25.0 26.0 27.0 28.0 29.0

【02x02】isnull() / notnull() 判断缺失值

isnull():为缺失值时为 True,否则为 False

notnull() 为缺失值时为 False,否则为 True

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> import numpy as np
>>> import pandas as pd
>>> obj = pd.Series([1, np.nan, 'hello', None])
>>> obj
0 1
1 NaN
2 hello
3 None
dtype: object
>>>
>>> obj.isnull()
0 False
1 True
2 False
3 True
dtype: bool
>>>
>>> obj.notnull()
0 True
1 False
2 True
3 False
dtype: bool

【02x03】dropna() 删除缺失值

dropna() 方法用于返回一个删除了缺失值的新 Series 或 DataFrame 对象。

在 Series 对象当中,dropna() 方法的语法如下(其他参数用法可参考在 DataFrame 中的应用):

Series.dropna(self, axis=0, inplace=False, how=None)

官方文档:https://pandas.pydata.org/docs/reference/api/pandas.Series.dropna.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> import numpy as np
>>> import pandas as pd
>>> obj = pd.Series([1, np.nan, 'hello', None])
>>> obj
0 1
1 NaN
2 hello
3 None
dtype: object
>>>
>>> obj.dropna()
0 1
2 hello
dtype: object

在 DataFrame 对象中,dropna() 方法的语法如下:

DataFrame.dropna(self, axis=0, how='any', thresh=None, subset=None, inplace=False)

官方文档:https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.dropna.html

参数 描述
axis 确定是否删除包含缺失值的行或列
0'index':删除包含缺失值的行。1'columns':删除包含缺失值的列
how 'any':如果存在任何NA值,则删除该行或列。'all':如果所有值都是NA,则删除该行或列
thresh 设置行或列中非缺失值的最小数量

不传递任何参数,将会删除任何包含缺失值的整行数据:

1
2
3
4
5
6
7
8
9
10
11
12
>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.DataFrame([[1, np.nan, 2], [2, 3, 5], [np.nan, 4, 6]])
>>> obj
0 1 2
0 1.0 NaN 2
1 2.0 3.0 5
2 NaN 4.0 6
>>>
>>> obj.dropna()
0 1 2
1 2.0 3.0 5

指定 axis 参数,删除包含缺失值的行或列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.DataFrame([[1, np.nan, 2], [2, 3, 5], [np.nan, 4, 6]])
>>> obj
0 1 2
0 1.0 NaN 2
1 2.0 3.0 5
2 NaN 4.0 6
>>>
>>> obj.dropna(axis='columns')
2
0 2
1 5
2 6

指定 how 参数,'any':如果存在任何NA值,则删除该行或列。'all':如果所有值都是NA,则删除该行或列:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.DataFrame([[1, np.nan, 2, np.nan], [2, 3, 5, np.nan], [np.nan, 4, 6, np.nan]])
>>> obj
0 1 2 3
0 1.0 NaN 2 NaN
1 2.0 3.0 5 NaN
2 NaN 4.0 6 NaN
>>> obj.dropna(axis='columns', how='all')
0 1 2
0 1.0 NaN 2
1 2.0 3.0 5
2 NaN 4.0 6

指定 thresh 参数,设置行或列中非缺失值的最小数量,以下示例中,第一行和第三行只有两个非缺失值,所以会被删除:

1
2
3
4
5
6
7
8
9
10
11
12
>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.DataFrame([[1, np.nan, 2, np.nan], [2, 3, 5, np.nan], [np.nan, 4, 6, np.nan]])
>>> obj
0 1 2 3
0 1.0 NaN 2 NaN
1 2.0 3.0 5 NaN
2 NaN 4.0 6 NaN
>>>
>>> obj.dropna(axis='rows', thresh=3)
0 1 2 3
1 2.0 3.0 5 NaN

【02x04】fillna() 填充缺失值

fillna() 方法可以将缺失值替换成有效的数值。

在 Series 对象中,fillna() 方法的语法如下:

Series.fillna(self, value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)

官方文档:https://pandas.pydata.org/docs/reference/api/pandas.Series.fillna.html

参数 描述
value 用于填充的值(例如 0),或者是一个 dict / Series / DataFrame 值
指定要用于每个 index(对于 Series)或column(对于 DataFrame)的值
不在dict / Series / DataFrame中的值将不被填充。此值不能是列表
method 填充方法:None
‘pad’ / ‘ffill’:将上一个有效观测值向前传播到下一个有效观测值
‘backfill’ / ‘bfill’:使用下一个有效观察值来填补空白
axis 0 or ‘index’,要填充缺失值的轴
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
>>> import pandas as pd
>>> obj = pd.Series([1, np.nan, 2, None, 3], index=list('abcde'))
>>> obj
a 1.0
b NaN
c 2.0
d NaN
e 3.0
dtype: float64
>>>
>>> obj.fillna(0)
a 1.0
b 0.0
c 2.0
d 0.0
e 3.0
dtype: float64
>>>
>>> obj.fillna(method='ffill')
a 1.0
b 1.0
c 2.0
d 2.0
e 3.0
dtype: float64
>>>
>>> obj.fillna(method='bfill')
a 1.0
b 2.0
c 2.0
d 3.0
e 3.0
dtype: float64

在 DataFrame 对象中,fillna() 方法的语法如下:

DataFrame.fillna(self, value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)

官方文档:https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.fillna.html

参数 描述
value 用于填充的值(例如 0),或者是一个 dict / Series / DataFrame 值
指定要用于每个 index(对于 Series)或column(对于 DataFrame)的值
不在dict / Series / DataFrame中的值将不被填充。此值不能是列表
method 填充方法:None
‘pad’ / ‘ffill’:将上一个有效观测值向前传播到下一个有效观测值
‘backfill’ / ‘bfill’:使用下一个有效观察值来填补空白
axis 0 or ‘index’1 or ‘columns’,要填充缺失值的轴

在 DataFrame 对象中的用法和在 Series 对象中的用法大同小异,只不过 axis 参数多了一个选择:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> import pandas as pd
>>> import numpy as np
>>> obj = pd.DataFrame([[1, np.nan, 2, np.nan], [2, 3, 5, np.nan], [np.nan, 4, 6, np.nan]])
>>> obj
0 1 2 3
0 1.0 NaN 2 NaN
1 2.0 3.0 5 NaN
2 NaN 4.0 6 NaN
>>>
>>> obj.fillna(method='ffill', axis=1)
0 1 2 3
0 1.0 1.0 2.0 2.0
1 2.0 3.0 5.0 5.0
2 NaN 4.0 6.0 6.0

1
2
3
4
5
这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106743778
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!


您的喜欢是作者写作最大的动力!❤️
  • PayPal
  • AliPay
  • WeChatPay
  • QQPay
Donate

 评论


Copyright 2018-2020 TRHX'S BLOG ICP 鄂ICP备19003281号-4MOE ICP 萌ICP备20202022号 正在载入... 百度统计

UV
PV
WordCount299.2k