CSDN 课程推荐:《迈向数据科学家:带你玩转Python数据分析》,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员;已出版《跟老齐学Python:轻松入门》《跟老齐学Python:Django实战》、《跟老齐学Python:数据分析》和《Python大学实用教程》畅销图书。
Pandas 系列文章(正在更新中…):
另有 NumPy、Matplotlib 系列文章已更新完毕,欢迎关注:
推荐学习资料与网站(博主参与部分文档翻译):
这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106743778
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!
Pandas 继承了 NumPy 的功能,NumPy 的基本能力之一是快速对每个元素进行运算,既包括基本算术运算(加、减、乘、除),也包括更复杂的运算(三角函数、指数函数和对数函数等)。具体可以参考 NumPy 系列文章。
因为 Pandas 是建立在 NumPy 基础之上的,所以 NumPy 的通用函数同样适用于 Pandas 的 Series 和 DataFrame 对象,如下所示:
>>> 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 对象:
>>> 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
>>> 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
Pandas 最重要的一个功能是,它可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。自动的数据对齐操作会在不重叠的索引处引入缺失值,即 NaN,缺失值会在算术运算过程中传播。
Series 对象的数据对齐操作:
>>> 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 对象的数据对齐操作会同时发生在行和列上:
>>> 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
首先回忆 NumPy 中的广播(参见:《Python 数据分析三剑客之 NumPy(二):数组索引 / 切片 / 广播 / 拼接 / 分割》),跟不同维度的 NumPy 数组一样,DataFrame 和 Series 之间算术运算也是有明确规定的。首先回忆一下 NumPy 中不同维度的数组之间的运算:
>>> 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 的列,然后沿着行一直向下广播:
>>> 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 的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集:
>>> 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)并进行广播:
>>> 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
完整的 Pandas 算术方法见下表:
方法 | 副本 | 描述 |
---|---|---|
add() | radd() | 加法(+) |
sub()、subtract() | rsub() | 减法(-) |
mul()、multiply() | rmul() | 乘法(*) |
pow() | rpow() | 指数(**) |
truediv()、div()、divide() | rdiv() | 除法(/) |
floordiv() | rfloordiv() | 底除(//) |
mod() | rmod() | 求余(%) |
副本均为原方法前加了个 r
,它会翻转参数:
>>> 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
这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106743778
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!
在现实中遇到的数据很少是干净整齐的,许多数据集都会有数据缺失的现象,缺失值主要有三种形式:null、NaN(NAN,nan) 或 NA。
使用 add
, sub
, div
, mul
等算术方法时,通过 fill_value
指定填充值,未对齐的数据将和填充值做运算。
Series 中的应用:
>>> 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 中的应用:
>>> 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
isnull()
:为缺失值时为 True
,否则为 False
;
notnull()
为缺失值时为 False
,否则为 True
。
>>> 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
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
>>> 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 | 设置行或列中非缺失值的最小数量 |
不传递任何参数,将会删除任何包含缺失值的整行数据:
>>> 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 参数,删除包含缺失值的行或列:
>>> 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,则删除该行或列:
>>> 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 参数,设置行或列中非缺失值的最小数量,以下示例中,第一行和第三行只有两个非缺失值,所以会被删除:
>>> 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
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’ ,要填充缺失值的轴 |
>>> 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 参数多了一个选择:
>>> 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
这里是一段防爬虫文本,请读者忽略。
本文原创首发于 CSDN,作者 TRHX。
博客首页:https://itrhx.blog.csdn.net/
本文链接:https://itrhx.blog.csdn.net/article/details/106743778
未经授权,禁止转载!恶意转载,后果自负!尊重原创,远离剽窃!