#!/usr/bin/env python # coding: utf-8 # # CHAPTER 7 Data Cleaning and Preparation # # 其实数据分析中80%的时间都是在数据清理部分,loading, clearning, transforming, rearranging。而pandas非常适合用来执行这些任务。 # # # 7.1 Handling Missing Data # # 在pandas中,missing data呈现的方式有些缺点的,但对大部分用户能起到足够的效果。对于数值型数据,pandas用浮点值Nan(Not a Number)来表示缺失值。我们称之为识别符(sentinel value),这种值能被轻易检测到: # In[3]: import pandas as pd import numpy as np # In[4]: string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado']) string_data # In[5]: string_data.isnull() # 在pandas中,我们使用了R语言中的一些传统,把缺失值表示为NA(not available)。在统计应用里,NA数据别是要么是数据不存在,要么是存在但不能被检测到。做数据清理的时候,对缺失值做分析是很重要的,我们要确定是否是数据收集的问题,或者缺失值是否会带来潜在的偏见。 # # 内建的Python None值也被当做NA: # In[6]: string_data[0] = None # In[7]: string_data.isnull() # 这里有一些用来处理缺失值的函数: # # ![](http://oydgk2hgw.bkt.clouddn.com/pydata-book/zq0q8.png) # # # 1 Filtering Out Missing Data(过滤缺失值) # # 有一些方法来过滤缺失值。可以使用pandas.isnull和boolean indexing, 配合使用dropna。对于series,只会返回non-null数据和index values: # In[8]: from numpy import nan as NA # In[9]: data = pd.Series([1, NA, 3.5, NA, 7]) # In[10]: data.dropna() # 上面的等同于: # In[11]: data[data.notnull()] # 对于DataFrame,会复杂一些。你可能想要删除包含有NA的row和column。dropna默认会删除包含有缺失值的row: # In[15]: data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA], [NA, NA, NA], [NA, 6.5, 3.]]) data # In[16]: cleaned = data.dropna() # In[18]: cleaned # 设定`how=all`只会删除那些全是NA的行: # In[19]: data.dropna(how='all') # 删除列也一样,设置axis=1: # In[20]: data[4] = NA data # In[21]: data.dropna(axis=1, how='all') # 一种删除DataFrame row的相关应用是是time series data。假设你想要保留有特定数字的观测结果,可以使用thresh参数: # In[22]: df = pd.DataFrame(np.random.randn(7, 3)) # In[23]: df # In[25]: df.iloc[:4, 1] = NA df # In[26]: df.iloc[:2, 2] = NA df # In[27]: df.dropna() # In[28]: df.dropna(thresh=2) # # 2 Filling In Missing Data(填补缺失值) # # 不是删除缺失值,而是用一些数字填补。对于大部分目的,fillna是可以用的。调用fillna的时候设置好一个常用用来替换缺失值: # In[29]: df.fillna(0) # 给fillna传入一个dict,可以给不同列替换不同的值: # In[30]: df.fillna({1: 0.5, 2: 0}) # fillna返回一个新对象,但你可以使用in-place来直接更改原有的数据: # In[32]: _ = df.fillna(0, inplace=True) df # 在使用fillna的时候,这种插入法同样能用于reindexing: # In[34]: df = pd.DataFrame(np.random.randn(6, 3)) df # In[36]: df.iloc[2:, 1] = NA df # In[37]: df.iloc[4:, 2] = NA df # In[38]: df.fillna(method='ffill') # In[39]: df.fillna(method='ffill', limit=2) # 使用fillna可以我们做一些颇有创造力的事情。比如,可以传入一个series的平均值或中位数: # In[40]: data = pd.Series([1., NA, 3.5, NA, 7]) data.fillna(data.mean()) # 下面是fillna的一些参数: # # ![](http://oydgk2hgw.bkt.clouddn.com/pydata-book/vtzrf.png) # In[ ]: