当前位置:主页 > 查看内容

手把手教你用pandas处理缺失值

发布时间:2021-04-18 00:00| 位朋友查看

简介:pandas对象的所有描述性统计信息默认情况下是排除缺失值的。 pandas对象中表现缺失值的方式并不完美,但是它对大部分用户来说是有用的。对于数值型数据,pandas使用浮点值NaN(Not a Number来表示缺失值)。我们称NaN为容易检测到的标识值: In : string_dat……

pandas对象的所有描述性统计信息默认情况下是排除缺失值的。

pandas对象中表现缺失值的方式并不完美,但是它对大部分用户来说是有用的。对于数值型数据,pandas使用浮点值NaN(Not a Number来表示缺失值)。我们称NaN为容易检测到的标识值:

In : 

  1. string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado']) 
  1. string_data 

Out:

  1. 0      aardvark  
  2. 1     artichoke  
  3. 2            NaN  
  4. 3       avocado  
  5. dtype: object 

In:

  1. string_data.isnull() 

Out:

  1. 0     False  
  2. 1     False  
  3. 2      True  
  4. 3     False  
  5. dtype: bool 

在pandas中,我们采用了R语言中的编程惯例,将缺失值成为NA,意思是not available(不可用)。在统计学应用中,NA数据可以是不存在的数据或者是存在但不可观察的数据(例如在数据收集过程中出现了问题)。当清洗数据用于分析时,对缺失数据本身进行分析以确定数据收集问题或数据丢失导致的数据偏差通常很重要。

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

In:

  1. string_data[0] = None 
  1. string_data.isnull() 

Out:

  1. 0      True  
  2. 1     False  
  3. 2      True  
  4. 3     False  
  5. dtype: bool 

pandas项目持续改善处理缺失值的内部细节,但是用户API函数,比如pandas. isnull,抽象掉了很多令人厌烦的细节。处理缺失值的相关函数列表如下:

  •  dropna:根据每个标签的值是否是缺失数据来筛选轴标签,并根据允许丢失的数据量来确定阈值
  •  fillna:用某些值填充缺失的数据或使用插值方法(如“ffill”或“bfill”)。
  •  isnull:返回表明哪些值是缺失值的布尔值
  •  notnull:isnull的反作用函数

01 过滤缺失值

有多种过滤缺失值的方法。虽然你可以使用pandas.isnull和布尔值索引手动地过滤缺失值,但dropna在过滤缺失值时是非常有用的。在Series上使用dropna,它会返回Series中所有的非空数据及其索引值:

In:

  1. from numpy import nan as NA  
  1. data = pd.Series([1, NA, 3.5, NA, 7]) 
  1. data.dropna() 

Out:

  1. 0     1.0  
  2. 2     3.5  
  3. 4     7.0  
  4. dtype: float64 

上面的例子与下面的代码是等价的:

In:

  1. data[data.notnull()] 

Out:

  1. 0     1.0  
  2. 2     3.5  
  3. 4     7.0  
  4. dtype: float64 

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

In:

  1. data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA]  
  2.                      [NA, NA, NA], [NA, 6.5, 3.]])  
  1. cleaned = data.dropna()  
  1. data 

Out:

  1.    0     1     2  
  2. 0  1.0  6.5  3.0  
  3. 1  1.0  NaN  NaN  
  4. 2  NaN  NaN  NaN  
  5. 3  NaN  6.5  3.0 

In:

  1. cleaned 

Out:

  1. 0     1     2  
  2.  1.0  6.5  3.0 

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

In:

  1. data.dropna(how='all'

Out:

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

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

In:

  1. data[4] = NA  
  1. data 

Out:

  1.      0    1    2   4  
  2. 0  1.0  6.5  3.0 NaN  
  3. 1  1.0  NaN  NaN NaN  
  4. 2  NaN  NaN  NaN NaN  
  5. 3  NaN  6.5  3.0 NaN 

In:

  1. data.dropna(axis=1how='all'

Out:

  1.      0    1    2  
  2. 0  1.0  6.5  3.0  
  3. 1  1.0  NaN  NaN  
  4. 2  NaN  NaN  NaN  
  5. 3  NaN  6.5  3.0 

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

In:

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

Out:

  1.           0         1         2  
  2. 0 -0.204708       NaN       NaN  
  3. 1 -0.555730       NaN       NaN  
  4. 2  0.092908       NaN  0.769023  
  5. 3  1.246435       NaN -1.296221  
  6. 4  0.274992  0.228913  1.352917  
  7. 5  0.886429 -2.001637 -0.371843  
  8. 6  1.669025 -0.438570 -0.539741 

In:

  1. df.dropna() 

Out:

  1.          0         1         2  
  2. 4 0.274992  0.228913  1.352917  
  3. 5 0.886429 -2.001637 -0.371843  
  4. 6 1.669025 -0.438570 -0.539741 

In:

  1. df.dropna(thresh=2

Out:

  1.          0         1         2  
  2. 2 0.092908       NaN  0.769023  
  3. 3 1.246435       NaN -1.296221  
  4. 4 0.274992  0.228913  1.352917  
  5. 5 0.886429 -2.001637 -0.371843  
  6. 6 1.669025 -0.438570 -0.539741 

02 补全缺失值

你有时可能需要以多种方式补全“漏洞”,而不是过滤缺失值(也可能丢弃其他数据)。

大多数情况下,主要使用fillna方法来补全缺失值。调用fillna时,可以使用一个常数来替代缺失值:

In:

  1. df.fillna(0) 

Out:

  1.           0         1         2  
  2. 0 -0.204708  0.000000  0.000000  
  3. 1 -0.555730  0.000000  0.000000  
  4. 2  0.092908  0.000000  0.769023  
  5. 3  1.246435  0.000000 -1.296221  
  6. 4  0.274992  0.228913  1.352917  
  7. 5  0.886429 -2.001637 -0.371843  
  8. 6  1.669025 -0.438570 -0.539741 

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

In:

  1. df.fillna({1: 0.5, 2: 0}) 

Out:

  1.          0         1         2  
  2. 0 -0.204708  0.500000  0.000000  
  3. 1 -0.555730  0.500000  0.000000  
  4. 2  0.092908  0.500000  0.769023  
  5. 3  1.246435  0.500000 -1.296221  
  6. 4  0.274992  0.228913  1.352917  
  7. 5  0.886429 -2.001637 -0.371843  
  8. 6  1.669025 -0.438570 -0.539741 

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

In:

  1. _ = df.fillna(0, inplace=True
  1. df 

Out:

  1.         0         1         2  
  2. 0 -0.204708  0.000000  0.000000  
  3. 1 -0.555730  0.000000  0.000000  
  4. 2  0.092908  0.000000  0.769023  
  5. 3  1.246435  0.000000 -1.296221  
  6. 4  0.274992  0.228913  1.352917  
  7. 5  0.886429 -2.001637 -0.371843  
  8. 6  1.669025 -0.438570 -0.539741 

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

In:

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

Out:

  1.          0         1         2  
  2. 0  0.476985  3.248944 -1.021228  
  3. 1 -0.577087  0.124121  0.302614  
  4. 2  0.523772       NaN  1.343810  
  5. 3 -0.713544       NaN -2.370232  
  6. 4 -1.860761       NaN       NaN  
  7. 5 -1.265934       NaN       NaN 

In:

  1. df.fillna(method='ffill'

Out:

  1.           0         1         2  
  2. 0  0.476985  3.248944 -1.021228  
  3. 1 -0.577087  0.124121  0.302614  
  4. 2  0.523772  0.124121  1.343810  
  5. 3 -0.713544  0.124121 -2.370232  
  6. 4 -1.860761  0.124121 -2.370232  
  7. 5 -1.265934  0.124121 -2.370232 

In:

  1. df.fillna(method='ffill'limit=2

Out:

  1.         0         1         2  
  2. 0  0.476985  3.248944 -1.021228  
  3. 1 -0.577087  0.124121  0.302614  
  4. 2  0.523772  0.124121  1.343810  
  5. 3 -0.713544  0.124121 -2.370232  
  6. 4 -1.860761       NaN -2.370232  
  7. 5 -1.265934       NaN -2.370232 

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

In:

  1. data = pd.Series([1., NA, 3.5, NA, 7])  
  1. data.fillna(data.mean()) 

Out:

  1. 0     1.000000  
  2. 1     3.833333  
  3. 2     3.500000  
  4. 3     3.833333  
  5. 4     7.000000  
  6. dtype: float64 

以下是fillna的函数参数。

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

关于作者:韦斯·麦金尼(Wes McKinney)是流行的Python开源数据分析库pandas的创始人。他是一名活跃的演讲者,也是Python数据社区和Apache软件基金会的Python/C++开源开发者。目前他在纽约从事软件架构师工作。

本文摘编自《利用Python进行数据分析》(原书第2版),经出版方授权发布。


本文转载自网络,原文链接:https://mp.weixin.qq.com/s/jgwYC40D2sgy1DshjoOllw
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文

  • 周排行
  • 月排行
  • 总排行

随机推荐