《利用Python进行数据分析》第七章——数据清洗与准备


前言

在本章中,我将讨论用于缺失值、重复值、字符串操作和其他分析数据转换的工具。而这篇文章中主要介绍如何处理数据的缺失值。


一、处理缺失值

缺失数据会在很多数据分析应用中出现。pandas的目标之一就是尽可能无痛地处理缺失值。对于数据型数据,pandas使用浮点值NaN(Not a Number来表示缺失值)。我们称NaN为容易检测到的标识值:

import numpy as np
import pandas as pd

string_data = pd.Series(['Magnum', 'Boost', np.nan, 'Zombie'])
print(string_data)
-----------------------------------------------------------
0    Magnum
1     Boost
2       NaN
3    Zombie
dtype: object

a = string_data.isnull()
print(a)
-----------------------------------------------------------
0    False
1    False
2     True
3    False
dtype: bool

在统计学的应用中,NA数据可以是不存在的数据或是存在但不可以观察的数据(例如在数据收集过程中出现了问题)。当清洗数据用于分析时,对缺失数据本身进行分析以确定数据收集问题或数据丢失导致的数据偏差通常很重要。

而Python内建的None值在对象数组中也被当作NA处理:

string_data[0] = None
a = string_data.isnull()
print(a)
-----------------------------------------------------------
0     True
1    False
2     True
3    False
dtype: bool

而下表是处理缺失值的相关函数列表:

函数名描述
dropna根据每个标签的值是否是缺失数据来筛选轴标签,并根据允许丢失的数据量来确定阔值
fillna用某些值填充缺失的数据或使用插值方法(如‘ffill’或‘bfill’)
isnull返回表明哪些值是缺失值的布尔值
notnull返回表明哪些值不是缺失值的布尔值

1.1 过滤缺失值

有多种过滤缺失值的方法,但这里推荐用dropna在过滤缺失值时是非常有用的。在Series上使用dropna,它会返回Series中所有的非空数据及其索引值:

from numpy import nan as NA
data = pd.Series([1, NA, 3.5, NA, 7])
a1 = data.dropna()
print(a1)
-----------------------------------------------------------
0    1.0
2    3.5
4    7.0
dtype: float64

而也可以使用pandas.notnull和布尔值索引手动地过滤缺失值:

a2 = data[data.notnull()]
print(a2)
-----------------------------------------------------------
0    1.0
2    3.5
4    7.0
dtype: float64

当处理DataFrame对象时,事情会稍微更复杂一点。你可能想要删除全部为NA或包含有NA的行或列。dropna默认情况下会删除包含缺失值的行:

data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA], [NA, NA, NA], [NA, 6.5, 3.]])
print(data)

a3 = data.dropna()
print(a3)
-----------------------------------------------------------
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0

     0    1    2
0  1.0  6.5  3.0

传入how=‘all’时,将删除所有值均为NA的行:

a3 = data.dropna(how='all')
print(a3)
-----------------------------------------------------------
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
3  NaN  6.5  3.0

如果要用同样的方式去删除列,传入参数axis = 1:

data[4] = NA
print(data)
a3 = data.dropna(axis=1, how='all')
print(a3)
-----------------------------------------------------------
     0    1    2   4
0  1.0  6.5  3.0 NaN
1  1.0  NaN  NaN NaN
2  NaN  NaN  NaN NaN
3  NaN  6.5  3.0 NaN

     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0

过滤DataFrame的行的相关方法往往涉及时间序列数据。假设你只想保留包含一定数量的观察值的行。你可以用thresh参数来表示:

df = pd.DataFrame(np.random.randn(7, 3))
df.iloc[:4,1]=NA
df.iloc[:2,2]=NA
print(df)

a1 = df.dropna()
print(a1)
a1 = df.dropna(thresh=2)
print(a1)
-----------------------------------------------------------
          0         1         2
0  0.720073       NaN       NaN
1  0.767735       NaN       NaN
2 -0.281442       NaN -0.296163
3 -1.132465       NaN -0.091511
4  1.839087  0.496217  0.854375
5 -0.283565  1.803889  1.011844
6 -1.226932  1.123181  0.540297

          0         1         2
4  1.839087  0.496217  0.854375
5 -0.283565  1.803889  1.011844
6 -1.226932  1.123181  0.540297

          0         1         2
2 -0.281442       NaN -0.296163
3 -1.132465       NaN -0.091511
4  1.839087  0.496217  0.854375
5 -0.283565  1.803889  1.011844
6 -1.226932  1.123181  0.540297

1.2 补全缺失值

有时可能需要以多种方式补全”漏洞“,而不是过滤缺失值(也可能丢失其他数据)。
而大多数情况下,主要使用fillna方法来补全缺失值。调用fillna时,你可以使用一个常熟来替代缺失值:

df = pd.DataFrame(np.random.randn(7, 3))
df.iloc[:4,1]=NA
df.iloc[:2,2]=NA
print(df)
a1 = df.fillna(0)
print(a1)
-----------------------------------------------------------
          0         1         2
0 -0.329325       NaN       NaN
1  0.317079       NaN       NaN
2  0.681410       NaN -1.181260
3 -1.520181       NaN -1.147875
4  0.325974 -0.211536 -0.786885
5 -2.235934 -0.243977 -0.002898
6 -1.396350  0.434119  1.040336

         0         1         2
0 -0.329325  0.000000  0.000000
1  0.317079  0.000000  0.000000
2  0.681410  0.000000 -1.181260
3 -1.520181  0.000000 -1.147875
4  0.325974 -0.211536 -0.786885
5 -2.235934 -0.243977 -0.002898
6 -1.396350  0.434119  1.040336

在调用fillna时使用字典,你可以为不同列设定不同的填充值:

a2 = df.fillna({1: 0.5, 2: 1})
print(a2)
-----------------------------------------------------------
          0         1         2
0 -0.329325  0.500000  1.000000
1  0.317079  0.500000  1.000000
2  0.681410  0.500000 -1.181260
3 -1.520181  0.500000 -1.147875
4  0.325974 -0.211536 -0.786885
5 -2.235934 -0.243977 -0.002898
6 -1.396350  0.434119  1.040336

fillna返回的是一个新的对象,但你也可以修改已经存在的对象:

_ = df.fillna(0,inplace=True)
print(df)
-----------------------------------------------------------
          0         1         2
0 -0.329325  0.000000  0.000000
1  0.317079  0.000000  0.000000
2  0.681410  0.000000 -1.181260
3 -1.520181  0.000000 -1.147875
4  0.325974 -0.211536 -0.786885
5 -2.235934 -0.243977 -0.002898
6 -1.396350  0.434119  1.040336

用于重建索引的相同的插值方法也可以用于fillna:

df1 = pd.DataFrame(np.random.randn(6,3))
df1.iloc[2:,1] = NA
df1.iloc[4:,1] = NA
print(df1)
a = df1.fillna(method='ffill')
print(a)
a1 = df1.fillna(method='ffill',limit=2)
print(a1)
-----------------------------------------------------------
          0         1         2
0 -0.702226  1.056195 -0.270062
1  0.279172 -1.344906 -0.829725
2  1.465186       NaN -0.496893
3  1.251037       NaN -0.111011
4 -1.290758       NaN       NaN
5  0.607567       NaN       NaN

          0         1         2
0 -0.702226  1.056195 -0.270062
1  0.279172 -1.344906 -0.829725
2  1.465186 -1.344906 -0.496893
3  1.251037 -1.344906 -0.111011
4 -1.290758 -1.344906 -0.111011
5  0.607567 -1.344906 -0.111011

          0         1         2
0 -0.702226  1.056195 -0.270062
1  0.279172 -1.344906 -0.829725
2  1.465186 -1.344906 -0.496893
3  1.251037 -1.344906 -0.111011
4 -1.290758       NaN -0.111011
5  0.607567       NaN -0.111011

使用fillna你可以完成很多带有一点创造性的工作。例如,你可以将Series的平均值或中位数用于填充缺失值:

data = pd.Series([1.,NA,3.5,NA,7])
print(data)
a = data.fillna(data.mean())
print(a)
-----------------------------------------------------------
0    1.000000
1    3.833333
2    3.500000
3    3.833333
4    7.000000
dtype: float64

下表则是fillna函数参数参考表:

参数描述
value标量值或字典型对象用于填充缺失值
method插值方法,如果没有其他参数,默认是‘ffill’
axis需要填充的值,默认值axis = 0
inplace修改被调用的对象,而不是生成一个备份
limit用于前向或后向填充时最大填充范围

总结

以上就是今天要讲的内容,本文仅仅简单介绍了pandas中处理缺失值的方式:过滤填充值和填充缺失值。除此之外还有能够处理缺失值的 isnull和notnull方法。下班!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值