许多原始数据集中会包含缺失值,这里总结一下常见的对缺失值的处理方式,以及如何通过pandas进行实际操作。
生成一个包含缺失值的DataFrame
通过如下代码,可以构造一个包含缺失值的DataFrame。这里用到一个小技巧,首先我们通过numpy的random
方法构造了一个包含随机值的DataFrame,然后,用reindex
方法添加了几个新的index,这样DataFrame里新增行的初始值就是NaN
了。后面我们都通过这种方法,在原始DataFrame的基础上构造包含缺失值的DataFrame。
代码:
import pandas as pdimport numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three']) print(df) print('\n') df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print(df)
输出:
one two threea -0.579503 0.423280 0.452675c -0.468805 -0.321307 0.891258e 0.168585 1.008384 -0.630137f 0.574003 -1.347813 -0.951535h -0.529655 -1.068217 -0.919875 one two threea -0.579503 0.423280 0.452675b NaN NaN NaNc -0.468805 -0.321307 0.891258d NaN NaN NaNe 0.168585 1.008384 -0.630137f 0.574003 -1.347813 -0.951535g NaN NaN NaNh -0.529655 -1.068217 -0.919875
缺失值检测
pandas提供了缺失值的检测方法isnull
,该方法通过布尔值的形式反馈某个值是否为缺失值。这样就可以便于观测缺失值,以及后续进一步地通过编程的方法批量地处理缺失值。isnull
还有一个镜像方法notnull
,以应对不同的编程场景。
代码:
import pandas as pdimport numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f','h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print(df) print('\n') print(df['one'].isnull())
输出:
one two threea -0.146791 -2.330160 -1.499680b NaN NaN NaNc -1.581122 0.734590 0.152708d NaN NaN NaNe 0.175039 -0.477513 -2.184527f 0.137429 2.458390 -0.452975g NaN NaN NaNh 0.102433 0.729506 1.236861a Falseb Truec Falsed Truee Falsef Falseg Trueh FalseName: one, dtype: bool
缺失值在求和运算中的行为
如果对一个包含缺失值的列进行求和运算时,缺失值会被当作0来处理。
代码:
import pandas as pdimport numpy as np df = pd.DataFrame(np.random.randn(2, 3), index=['a', 'c'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c']) print(df) print('\n') print(df['one'].sum())
输出:
one two threea -0.590257 0.941664 -0.320593b NaN NaN NaNc -0.237803 0.196062 0.323316-0.8280594903026121
用一个标量值填充缺失值
最简单的缺失值处理方法就是指定一个标量值来进行填充,比如0。
代码
import pandas as pdimport numpy as np df = pd.DataFrame(np.random.randn(3, 3), index=['a', 'c', 'e'],columns=['one','two', 'three']) df = df.reindex(['a', 'b', 'c']) print(df) print("\nNaN replaced with '0':") print(df.fillna(0))
输出:
one two three a 0.667195 -2.287430 0.261266b NaN NaN NaNc 0.568405 -0.860137 -1.784247NaN replaced with '0': one two three a 0.667195 -2.287430 0.261266b 0.000000 0.000000 0.000000c 0.568405 -0.860137 -1.784247
用临近值填充缺失值
另一个思路是用缺失值附近的值来对其进行填充,这种方法适用于一段连续数据,例如时间序列。pandas提供了pad/fill
方法来进行前向填充(用缺失值之前的数据来进行填充),也可以使用bfill/backfill
方法来进行后向填充。
代码
import pandas as pdimport numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f','h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print(df)print ("\nNaN replaced with forward values:")print (df.fillna(method='pad'))
输出:
one two threea 1.669808 -0.034507 -1.756447b NaN NaN NaNc 0.988920 0.496142 0.916299d NaN NaN NaNe -1.081201 -0.385207 -0.850673f -1.094450 0.412084 -1.412251g NaN NaN NaNh 0.786988 2.220630 -2.125072NaN replaced with forward values: one two threea 1.669808 -0.034507 -1.756447b 1.669808 -0.034507 -1.756447c 0.988920 0.496142 0.916299d 0.988920 0.496142 0.916299e -1.081201 -0.385207 -0.850673f -1.094450 0.412084 -1.412251g -1.094450 0.412084 -1.412251h 0.786988 2.220630 -2.125072
丢失缺失值
与填充缺失值的思路相比,在数据量足够多或者对数据要求较高的情况下,丢失缺失值未尝不是一个好办法。pandas提供了dropna
方法,该方法有一个参数axis
(默认值是0),为0时表示丢弃行(通常是一个样本),为1时表示丢弃列(通常是一个特征),可以根据分析结果来选择具体的丢弃方式。下面的代码表示了如何丢弃一行。
代码:
import pandas as pdimport numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f','h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print(df) print("\nNaN row dropped:") print(df.dropna())
输出:
one two threea -0.493792 0.946581 2.640122b NaN NaN NaNc -0.373698 0.461838 -1.692989d NaN NaN NaNe 1.593574 -0.713764 -0.208575f 0.362406 -0.305731 0.400795g NaN NaN NaNh -0.094171 1.114953 -0.038143NaN row dropped: one two threea -0.493792 0.946581 2.640122c -0.373698 0.461838 -1.692989e 1.593574 -0.713764 -0.208575f 0.362406 -0.305731 0.400795h -0.094171 1.114953 -0.038143
总结
本文描述了对缺失值处理的一些常见思路和对应的方法,但在实际应用中,还需要结合数据本身来选择最合适的处理方式。
作者:schnauzer
链接:https://www.jianshu.com/p/5f5202531956