移除重复数据
DataFrame中常常会出现重复行。如下面这个例子:
In [295]: data = DataFrame({'k1':['one']*3 + ['two'] * 4, 'k2':[1,1,2,3,3,4,4]})
In [296]: data
Out[296]:
k1 k2
0 one 1
1 one 1
2 one 2
3 two 3
4 two 3
5 two 4
6 two 4
DataFrame的duplicated
方法返回一个布尔型Series,表示各行是否是重复行:
In [297]: data.duplicated()
Out[297]:
0 False
1 True
2 False
3 False
4 True
5 False
6 True
dtype: bool
还有一个于此相关的drop_duplicates
方法,它用于返回一个移除了重复行的DataFrame:
In [298]: data.drop_duplicates()
Out[298]:
k1 k2
0 one 1
2 one 2
3 two 3
5 two 4
这两个方法默认会去判断全部列,也可以指定部分列来进行判断,这样其他列就会根据指定的列来做判断:
In [299]: data['v1'] = range(7)
In [300]: data.drop_duplicates(['k1'])
Out[300]:
k1 k2 v1
0 one 1 0
3 two 3 3
duplicated
和drop_duplicates
默认保留的是第一个出现的值的组合。传入take_last=True
则会保留最后一个:
In [305]: data.drop_duplicates(['k1','k2'],keep='last')
Out[305]:
k1 k2 v1
1 one 1 1
2 one 2 2
4 two 3 4
6 two 4 6
利用函数或者映射进行数据转换
在对数据集进行转换时,你可能希望根据数组、Series或DataFrame列中的值来实现该转换工作。如下:
In [307]: data = DataFrame({'food':['bacon','pulled pork','bacon', 'Pastrami','corned beed', 'Bacon
...: ', 'pastrami', 'honey ham', 'nova lox'], 'ounces':[4,3,12,6,7.5,8,3,5,6]})
In [308]: data
Out[308]:
food ounces
0 bacon 4.0
1 pulled pork 3.0
2 bacon 12.0
3 Pastrami 6.0
4 corned beed 7.5
5 Bacon 8.0
6 pastrami 3.0
7 honey ham 5.0
8 nova lox 6.0
假设你想要添加一列表示该肉类食物来源的动物类型。我们先编写一个肉类到动物的映射:
In [310]: meat_to_animal = {
'bacon':'pig',
'pulled pork':'pig',
'pastrami':'cow',
'corned beef':'cow',
'honey ham':'pig',
'nova lox':'salmon'}
Series的map
方法可以接受一个函数或含有映射关系的字典型对象,但是这里有一个问题,有些肉类的首字母大写了,而有些则没有。所以我们要把各个值转换成小写:
In [311]: data['animal'] = data['food'].map(str.lower).map(meat_to_animal)
In [313]: data
Out[313]:
food ounces animal
0 bacon 4.0 pig
1 pulled pork 3.0 pig
2 bacon 12.0 pig
3 Pastrami 6.0 cow
4 corned beed 7.5 NaN
5 Bacon 8.0 pig
6 pastrami 3.0 cow
7 honey ham 5.0 pig
8 nova lox 6.0 salmon
替换值
之前学到了利用fillna
方法填充缺失数据可以看做值替换的一种特殊情况。虽然前面提到的map
可用于修改对象的数据子集,而replace
则提供一种实现该功能的更简单、更灵活的方式:
In [317]: data = Series([1, -999, 2, -999, -1000, 3])
In [318]: data
Out[318]:
0 1
1 -999
2 2
3 -999
4 -1000
5 3
dtype: int64
-999这个值可能是一个表示缺失数据的值。要将其替换为pandas能够理解的NaN
值,那么我们可以利用replace
来产生一个新的Series:
In [319]: data.replace(-999, np.nan)
Out[319]:
0 1.0
1 NaN
2 2.0
3 NaN
4 -1000.0
5 3.0
dtype: float64
如果想一次性将多个值替换为NaN
值:
In [321]: data.replace([-999,-1000], np.nan)
Out[321]:
0 1.0
1 NaN
2 2.0
3 NaN
4 NaN
5 3.0
dtype: float64
如果相对不同的值做不同的替换,则传入一个由替换关系组成的列表即可:
In [322]: data.replace([-999,-1000], [np.nan, 0])
Out[322]:
0 1.0
1 NaN
2 2.0
3 NaN
4 0.0
5 3.0
dtype: float64
当然也可以是字典:
In [323]: data.replace({-999:np.nan, -1000: 0})
Out[323]:
0 1.0
1 NaN
2 2.0
3 NaN
4 0.0
5 3.0
dtype: float64