Pandas(2):缺失值即空值na判断及其处理

常用的pandas表格空值处理方式。如 (1) 删除包含空值的行或者列;(2) 填充某些列的空值为特定值;(3) 基于序列的插值。

空值定义

读取dataframe表格输出的控制都显示为“NAN”,但是具体的情况可能存在一些差别

pandas的数值类型基于numpy dtype,因此缺失值/空值也沿用了numpy。一些“空值”:

  1. None/pd.NA:Python中的空值表示,即所有的空值指向同一个地址。NA含义为not available.(is None)
  2. pd.NaN:这是非常常见的一个空值,它不等于None也不等于np.nan,是一个特殊的浮点数。要对它进行判断需要使用df.isna()/df.isnull/pd.isna(x)/pd.isnull(x)
  3. np.nan:该值是有值的,占内存,也是一个特殊的浮点数,因此如果导出含NAN的数据会使得该列为浮点型,占用空间增大NAN含义为not a number
  4. NaT:对于 datetime64[ns] 类型,使用NaT表示缺失值
  5. ‘’:空字符串,这里实际上也是有值的,但字符串长度为0。

如何判断是否为空值:df.isna(); df.notna();pd.isna(x),会返回True/False。在此基础上可以进行进一步计算,如df.loc[]的条件选择实际上就是基于中间的条件生成T/F的列然后进行mask筛选行列,具体可以参见之前的笔记

  • isnull()函数==isna()函数,但推荐用后者,便于记忆,与填充及删除时一致。
1
2
3
4
5
6
7
8
9
# 举例
# 输出某一列为空值的行
df.loc[df['colname']== None]
df.loc[df['colname']== pd.NA]
# nan
df.loc[df['colname'].isna()]
df.loc[df['colname'].isnull()]
# NaT
df.loc[df['colname']==pd.NaT()]

值的处理

什么时候对数值进行整列删除-意味着舍弃某指标或者整行删除-舍弃某条记录或者什么时候选择进行填充需要视具体的数据和需求来确定。

删除行或列dropna

DataFrame.dropna(axis=0, how=[‘any’, ‘all’], thresh, subset=None, inplace=False...)

  • axis=0表示默认删除包含空值的
  • subset用于指定某些列
  • how表示是全部为None才删除还是只要存在None就删除
  • thresh与how不能同时工作,表示删除多少个

常用df.dropna(subset=[])

1
2
3
4
5
6
7
8
9
10
# 删除全部空的行
df.dropna()
# 删除全部空的列
df.dropna(axis='columns')
df.dropna(axis=1)
df.dropna(axis=1, how='all')
# 只要存在空值就将列删除
df.dropna(axis=1, how='any')
# 删除某些列中存在空值的行
df.dropna(subset=['name', 'toy'])

填充fillna

常用的是df.fillna(0)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
df
A B C D
0 NaN 2.0 NaN 0.0
1 3.0 4.0 NaN 1.0
2 NaN NaN NaN NaN
3 NaN 3.0 NaN 4.0
# 全部填充
>>> df.fillna(0)
# 给不同的列填充不同的值,A列填充0
>>> values = {"A": 0, "B": 1, "C": 2, "D": 3}
>>> df.fillna(value=values)
A B C D
0 0.0 2.0 2.0 0.0
1 3.0 4.0 2.0 1.0
2 0.0 1.0 2.0 3.0
3 0.0 3.0 2.0 4.0
>>> df.fillna(value=values, limit=1)# 每一列只填充一次
A B C D
0 0.0 2.0 2.0 0.0
1 3.0 4.0 NaN 1.0
2 NaN 1.0 NaN 3.0
3 NaN 3.0 NaN 4.0

插值interpolate

关于时间序列的插值可以参阅此处,默认为线性插值(method=“linear”),常用,但默认不会填充第一个空值,需要填充时可以加上limit_direction

1
2
3
4
df['a1'] = df['a'].interpolate()
df['a1'] = df['a'].interpolate(limit_direction=‘both’)
# 所有列进行填充
df = df.interpolate(limit_direction=‘both’)

多项式插值df.interpolate(method='polynomial', order=2)

参考学习