简介
在数据处理中,Pandas会将无法解析的数据或者缺失的数据使用NaN来表示。虽然所有的数据都有了相应的表示,但是NaN很明显是无法进行数学运算的。
本文将会讲解Pandas对于NaN数据的处理方法。
NaN的例子
上面讲到了缺失的数据会被表现为NaN,我们来看一个具体的例子:
我们先来构建一个DF:
1 | less复制代码In [1]: df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'], |
上面DF只有acefh这几个index,我们重新index一下数据:
1 | sql复制代码In [5]: df2 = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) |
数据缺失,就会产生很多NaN。
为了检测是否NaN,可以使用isna()或者notna() 方法。
1 | sql复制代码In [7]: df2['one'] |
注意在Python中None是相等的:
1 | ini复制代码In [11]: None == None # noqa: E711 |
但是np.nan是不等的:
1 | ini复制代码In [12]: np.nan == np.nan |
整数类型的缺失值
NaN默认是float类型的,如果是整数类型,我们可以强制进行转换:
1 | ini复制代码In [14]: pd.Series([1, 2, np.nan, 4], dtype=pd.Int64Dtype()) |
Datetimes 类型的缺失值
时间类型的缺失值使用NaT来表示:
1 | sql复制代码In [15]: df2 = df.copy() |
None 和 np.nan 的转换
对于数字类型的,如果赋值为None,那么会转换为相应的NaN类型:
1 | ini复制代码In [21]: s = pd.Series([1, 2, 3]) |
如果是对象类型,使用None赋值,会保持原样:
1 | ini复制代码In [24]: s = pd.Series(["a", "b", "c"]) |
缺失值的计算
缺失值的数学计算还是缺失值:
1 | less复制代码In [28]: a |
但是在统计中会将NaN当成0来对待。
1 | less复制代码In [31]: df |
如果是在cumsum或者cumprod中,默认是会跳过NaN,如果不想统计NaN,可以加上参数skipna=False
1 | r复制代码In [34]: df.cumsum() |
使用fillna填充NaN数据
数据分析中,如果有NaN数据,那么需要对其进行处理,一种处理方法就是使用fillna来进行填充。
下面填充常量:
1 | sql复制代码In [42]: df2 |
还可以指定填充方法,比如pad:
1 | ini复制代码In [45]: df |
可以指定填充的行数:
1 | ini复制代码In [48]: df.fillna(method='pad', limit=1) |
fill方法统计:
方法名 | 描述 |
---|---|
pad / ffill | 向前填充 |
bfill / backfill | 向后填充 |
可以使用PandasObject来填充:
1 | less复制代码In [53]: dff |
上面操作等同于:
1 | css复制代码In [56]: dff.where(pd.notna(dff), dff.mean(), axis='columns') |
使用dropna删除包含NA的数据
除了fillna来填充数据之外,还可以使用dropna删除包含na的数据。
1 | ini复制代码In [57]: df |
插值interpolation
数据分析时候,为了数据的平稳,我们需要一些插值运算interpolate() ,使用起来很简单:
1 | yaml复制代码In [61]: ts |
1 | yaml复制代码In [64]: ts.interpolate() |
插值函数还可以添加参数,指定插值的方法,比如按时间插值:
1 | yaml复制代码In [67]: ts2 |
按index的float value进行插值:
1 | ini复制代码In [70]: ser |
除了插值Series,还可以插值DF:
1 | less复制代码In [73]: df = pd.DataFrame({'A': [1, 2.1, np.nan, 4.7, 5.6, 6.8], |
interpolate还接收limit参数,可以指定插值的个数。
1 | r复制代码In [95]: ser.interpolate(limit=1) |
使用replace替换值
replace可以替换常量,也可以替换list:
1 | ini复制代码In [102]: ser = pd.Series([0., 1., 2., 3., 4.]) |
1 | ini复制代码In [104]: ser.replace([0, 1, 2, 3, 4], [4, 3, 2, 1, 0]) |
可以替换DF中特定的数值:
1 | css复制代码In [106]: df = pd.DataFrame({'a': [0, 1, 2, 3, 4], 'b': [5, 6, 7, 8, 9]}) |
可以使用插值替换:
1 | ini复制代码In [108]: ser.replace([1, 2, 3], method='pad') |
本文已收录于 www.flydean.com/07-python-p…
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
本文转载自: 掘金