在进行数据分析和建模的过程中,大量时间花在数据准备上:加载,清理,转换和重新排列。pandas以及内置的python语言功能提供了一个高级灵活和快速的工具集,使你能够将数据处理为正确的形式。
7.1 处理缺失值
对于数值型数据,pandas使用NaN 来表示缺失值。我们称 NaN 为容易检测到的表示值:
string_data=pd.Series(['aardvark','artichoke',np.nan,'avocado'])
string_data.isnull()
0 False
1 False
2 True
3 False
dtype: bool
string_data[0]=None # None 值在对象数组中也被当作NA 处理
NA处理方法 | 描述 |
---|---|
dropna | 根据每个标签的值是否是缺失数据来筛选标签,并根据允许丢失的数据量来确定阈值 |
fillna | 用某些值填充缺失的数据或使用插值方法 |
insull/notnull | 判断是否是缺失值 |
7.1.1 过滤缺失值
虽然可以使用 pandas.isnull 和布尔值索引手动的过滤缺失值,但是 dropna 在过滤缺失值是很有用的。在Series 中使用,返回 Series 中所有非空数据以及其索引。
data=pd.Series([1,np.nan,3,5,np.nan,7]) # data[data.notnull()] 这个效果是一样的
data.dropna()
0 1.0
2 3.0
3 5.0
5 7.0
dtype: float64
处理 dataframe 对象时,你可能想要删除全部为NA 或包含有NA 的行或列。dropna 默认情况下会删除包含缺失值的行
data=pd.DataFrame([[1.,6.5,3.],[1.,np.nan,np.nan],[np.nan,np.nan,np.nan],[np.nan,6.5,3.]])
cleaned=data.dropna()
data
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
cleaned
0 1 2
0 1.0 6.5 3.0
data.dropna(how='all') # 这个就删除所有值都是 NA 的行
0 1 2
0 1.0 6.5 3.0
1 1.0 NaN NaN
3 NaN 6.5 3.0
data[4]=np.nan
data.dropna(axis=1,how='all') # 删除列,
data
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
# 过滤 dataframe 的行的相关方法往往涉及时间序列数据,假如你只需保留包含一定数量的观察值的行,可以用 thresh 参数来表示
df=pd.DataFrame(np.random.randn(7,3))
df.iloc[:4,1]=np.nan
df.iloc[:2,2]=np.nan
df
0 1 2
0 -0.018181 NaN NaN
1 -0.148029 NaN NaN
2 -1.068483 NaN 0.556369
3 -0.716866 NaN 1.273184
4 -0.690865 0.601410 0.467746
5 -2.681891 -0.556718 -0.529830
6 -0.572316 0.057732 -0.988892
df.dropna()
0 1 2
4 -0.690865 0.601410 0.467746
5 -2.681891 -0.556718 -0.529830
6 -0.572316 0.057732 -0.988892
df.dropna(thresh=2) # 保留非 NA 的数量,thresh=1 只要有一个是非NA 就保留。
0 1 2
2 -1.068483 NaN 0.556369
3 -0.716866 NaN 1.273184
4 -0.690865 0.601410 0.467746
5 -2.681891 -0.556718 -0.529830
6 -0.572316 0.057732 -0.988892
7.1.2 补全缺失值
df
0 1 2
0 -0.018181 NaN NaN
1 -0.148029 NaN NaN
2 -1.068483 NaN 0.556369
3 -0.716866 NaN 1.273184
4 -0.690865 0.601410 0.467746
5 -2.681891 -0.556718 -0.529830
6 -0.572316 0.057732 -0.988892
df.fillna('你好')
0 1 2
0 -0.018181 你好 你好
1 -0.148029 你好 你好
2 -1.068483 你好 0.556369
3 -0.716866 你好 1.27318
4 -0.690865 0.60141 0.467746
5 -2.681891 -0.556718 -0.52983
6 -0.572316 0.0577322 -0.988892
df.fillna({1:1,2:2},inplace=Ture) # 为不同的列设置不同的值,并且修改原对象。
0 1 2
0 -0.018181 1.000000 2.000000
1 -0.148029 1.000000 2.000000
2 -1.068483 1.000000 0.556369
3 -0.716866 1.000000 1.273184
4 -0.690865 0.601410 0.467746
5 -2.681891 -0.556718 -0.529830
6 -0.572316 0.057732 -0.988892
df=pd.DataFrame(np.random.randn(6,3))
df.iloc[2:,1]=np.nan
df.iloc[4:,2]=np.nan
df
0 1 2
0 0.697310 0.99049 1.108152
1 2.251352 -1.83455 2.832842
2 -0.359019 NaN -0.674754
3 -0.353238 NaN -0.714741
4 0.388780 NaN NaN
5 0.354652 NaN NaN
df.fillna(method='ffill',limit=2) # 向前插值,限制填充两次
0 1 2
0 0.697310 0.99049 1.108152
1 2.251352 -1.83455 2.832842
2 -0.359019 -1.83455 -0.674754
3 -0.353238 -1.83455 -0.714741
4 0.388780 NaN -0.714741
5 0.354652 NaN -0.714741
df.fillna(df.mean()) # 将缺失值补充为平均数
fillna 函数参数 | 描述 |
---|---|
value | 标量值或字典型对象,用于填充缺失值 |
method | 插值方法,默认是 ffill |
axis | 需要填充的轴,默认时 0 |
inplace | 修改原对象,而不是一个备份 |
limit | 用于向前或向后填充的最大范围 |
7.2.1 删除重复值
data = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'], # dataframe 会出现重复行
'k2': [1, 1, 2, 3, 3, 4, 4]})
data
k1 k2
0 one 1
1 two 1
2 one 2
3 two 3
4 one 3
5 two 4
6 two 4
data.duplicated() # 这个方法返回一个 series ,判断是否存在重复,与之前出现的行 相同。
0 False
1 False
2 False
3 False
4 False
5 False
6 True
dtype: bool
data.drop_duplicates() # 返回 dataframe 内容是 duplicated 返回数组中为False 的部分。
k1 k2
0 one 1
1 two 1
2 one 2
3 two 3
4 one 3
5 two 4
data['v1']=range(7) # 默认是对列的操作,可以指定任何子集来检测是否有重复,这里基于 k1 来去除重复值。
data.drop_duplicates(['k1'])
k1 k2 v1
0 one 1 0
1 two 1 1
data.drop_duplicates(['k1','k2'],keep='last') # 默认保留第一个观察到的值,传入keep 保留 最后一个
k1 k2 v1
0 one 1 0
1 two 1 1
2 one 2 2
3 two 3 3
4 one 3 4
6 two 4 6 # 5 这一行被去除,保留了后一个。。