在pandas中,missing data呈现的方式有些缺点的,但对大部分用户能起到足够的效果。对于数值型数据,pandas用浮点值Nan(Not a Number)来表示缺失值。我们称之为识别符(sentinel value),这种值能被轻易检测到 # 数据缺失 在pandas中,我们使用了R语言中的一些传统,把缺失值表示为NA(not available)。在统计应用里,NA数据别是要么是数据不存在,要么是存在但不能被检测到。做数据清理的时候,对缺失值做分析是很重要的,我们要确定是否是数据收集的问题,或者缺失值是否会带来潜在的偏见。 内建的Python None值也被当做NA
import pandas as pd
import numpy as np
from numpy import nan as NA
string_data = pd.Series(['aardvark', 'artichoke', NA, 'avocado'])
string_data
0 aardvark
1 artichoke
2 NaN
3 avocado
dtype: object
string_data.isnull()
0 False 1 False 2 True 3 False dtype: bool 这里有一些用来处理缺失值的函数: ![](http://oydgk2hgw.bkt.clouddn.com/pydata-book/zq0q8.png) ### 1、Filtering Out Missing Data(过滤缺失值) 有一些方法来过滤缺失值。可以使用pandas.isnull和boolean indexing, 配合使用dropna。对于series,只会返回non-null数据和index values:
# 直接过滤缺失值
data = pd.Series([1, NA, 3.5, NA, 7])
data.dropna()
0 1.0
2 3.5
4 7.0
dtype: float64
df = pd.DataFrame(np.random.randn(7, 3))
df
0 | 1 | 2 | |
---|---|---|---|
0 | -0.029785 | 0.110282 | -1.577633 |
1 | -1.489474 | -1.467383 | 0.006396 |
2 | -1.105860 | 0.476798 | -0.400001 |
3 | -1.573019 | 0.147722 | 0.250568 |
4 | -0.848726 | 1.002656 | 0.568422 |
5 | 1.457525 | 0.411282 | -0.257635 |
6 | 2.828644 | -1.237598 | -0.532588 |
df.iloc[:4, 1] = NA
df.iloc[:2, 2] = NA
df
0 | 1 | 2 | |
---|---|---|---|
0 | -0.029785 | NaN | NaN |
1 | -1.489474 | NaN | NaN |
2 | -1.105860 | NaN | -0.400001 |
3 | -1.573019 | NaN | 0.250568 |
4 | -0.848726 | 1.002656 | 0.568422 |
5 | 1.457525 | 0.411282 | -0.257635 |
6 | 2.828644 | -1.237598 | -0.532588 |
# 会删除行或列
df.dropna()
0 | 1 | 2 | |
---|---|---|---|
4 | -0.848726 | 1.002656 | 0.568422 |
5 | 1.457525 | 0.411282 | -0.257635 |
6 | 2.828644 | -1.237598 | -0.532588 |
df.dropna(thresh=2)
0 | 1 | 2 | |
---|---|---|---|
2 | -1.105860 | NaN | -0.400001 |
3 | -1.573019 | NaN | 0.250568 |
4 | -0.848726 | 1.002656 | 0.568422 |
5 | 1.457525 | 0.411282 | -0.257635 |
6 | 2.828644 | -1.237598 | -0.532588 |
2、Filling In Missing Data(填补缺失值)
在处理缺失值的时候,一些情况下我们会直接用dropna来把缺失值删除,但另一些情况下,我们希望用一些固定的值来代替缺失值,而fillna就是用来做这个的,例如,这里我们用平均值mean来代替缺失值NA
- fillna返回一个新对象,但你可以使用in-place来直接更改原有的数据
# 全部填充0
df.fillna(0)
0 | 1 | 2 | |
---|---|---|---|
0 | -0.029785 | 0.000000 | 0.000000 |
1 | -1.489474 | 0.000000 | 0.000000 |
2 | -1.105860 | 0.000000 | -0.400001 |
3 | -1.573019 | 0.000000 | 0.250568 |
4 | -0.848726 | 1.002656 | 0.568422 |
5 | 1.457525 | 0.411282 | -0.257635 |
6 | 2.828644 | -1.237598 | -0.532588 |
# 给fillna传入一个dict,可以给不同列替换不同的值
df.fillna({
1: 0.5, 2: 0})
0 | 1 | 2 | |
---|---|---|---|
0 | -0.029785 | 0.500000 | 0.000000 |
1 | -1.489474 | 0.500000 | 0.000000 |
2 | -1.105860 | 0.500000 | -0.400001 |
3 | -1.573019 | 0.500000 | 0.250568 |
4 | -0.848726 | 1.002656 | 0.568422 |
5 | 1.457525 | 0.411282 | -0.257635 |
6 | 2.828644 | -1.237598 | -0.532588 |
下面是fillna的一些参数:
states = ['Ohio', 'New York', 'Vermont', 'Florida',
'Oregon', 'Nevada', 'California', 'Idaho']
data = pd.Series(np.random.randn(8), index=states)
data[['Vermont', 'Nevada', 'Idaho']] = np.nan
data
Ohio 0.760579
New York 0.729209
Vermont NaN
Florida -2.195910
Oregon -0.658126
Nevada NaN
California -1.851410
Idaho NaN
dtype: float64
group_key = ['East'] * 4 + ['West'] * 4
data.groupby(group_key).mean()
East -0.235374
West -1.254768
dtype: float64
然后我们可以用每个组的平均值来填充NA:
fill_mean = lambda g: g.fillna(g.mean())
data.groupby(group_key).apply(fill_mean)
Ohio 0.760579
New York 0.729209
Vermont -0.235374
Florida -2.195910
Oregon -0.658126
Nevada -1.254768
California -1.851410
Idaho -1.254768
dtype: float64
在另外一些情况下,我们可能希望提前设定好用于不同组的填充值。因为group有一个name属性,我们可以利用这个:
fill_values = {
'East': 0.5, 'West': -1}
fill_func = lambda g: g.fillna(fill_values[g.name])
data.groupby(group_key).apply(fill_func)
Ohio 0.760579
New York 0.729209
Vermont 0.500000
Florida -2.195910
Oregon -0.658126
Nevada -1.000000
California -1.851410
Idaho -1.000000
dtype: float64
数据变换
1、删除重复值
data = pd.DataFrame({
'k1': ['one', 'two'] * 3 + ['two'],
'k2'</