1.删除重复值:
duplicated()
方法返回的是一个布尔型数据,反映的是每一行是否与之前出现的行有重复的情况。
df = pd.DataFrame({'名字':['小高','小刚','小强','小王','小明','小高'],'身高':[170,180,165,177,190,170]})
print(df)
print('-------------')
print(df.duplicated())
名字 身高
0 小高 170
1 小刚 180
2 小强 165
3 小王 177
4 小明 190
5 小高 170
-------------
0 False
1 False
2 False
3 False
4 False
5 True
dtype: bool
drop_duplicates()
方法返回的是DataFrame数据类型,内容为duplicates()
方法返回数组中为False的部分。
df_new = df.drop_duplicates()
print(df_new)
名字 身高
0 小高 170
1 小刚 180
2 小强 165
3 小王 177
4 小明 190
drop_duplicates()
方法还可以基于某一列来去除重复值。
df = pd.DataFrame({'名字':['小高','小刚','小强','小王','小明','小高'],'身高':[170,180,165,177,190,170]})
df['年龄段'] = ['90后','80后','80后','90后','90后','90后',]
print(df)
print('-------------')
df_new = df.drop_duplicates(['年龄段'])
print(df_new)
名字 身高 年龄段
0 小高 170 90后
1 小刚 180 80后
2 小强 165 80后
3 小王 177 90后
4 小明 190 90后
5 小高 170 90后
-------------
名字 身高 年龄段
0 小高 170 90后
1 小刚 180 80后
duplicated()
和drop_duplicates()
方法都是默认保留第一个观测到的值,可以通过传入参数keep=last
来保留最后一个。
df = pd.DataFrame({'名字':['小高','小刚','小强','小王','小明','小高'],'身高':[170,180,165,177,190,170]})
df['年龄段'] = ['90后','80后','80后','90后','90后','90后',]
print(df)
print('-------------')
df_new = df.drop_duplicates(['年龄段'],keep='last')
print(df_new)
名字 身高 年龄段
0 小高 170 90后
1 小刚 180 80后
2 小强 165 80后
3 小王 177 90后
4 小明 190 90后
5 小高 170 90后
-------------
名字 身高 年龄段
2 小强 165 80后
5 小高 170 90后
2.使用函数或映射进行数据转换:
使用map()方法可以便捷地执行按元素操作的方法。
df = pd.DataFrame({'Name':['Tom','jerry','Alexander','Jack','Aiden','Ryan'],'Height':[120,110,125,122,119,118]})
print(df)
print('-------------')
Name_to_Grade = {'tom':3,'jerry':1,'alexander':2,'jack':1,'aiden':3,'ryan':2}
df['Grade'] = df['Name'].map(lambda x:Name_to_Grade[x.lower()])
print(df)
Height Name
0 120 Tom
1 110 jerry
2 125 Alexander
3 122 Jack
4 119 Aiden
5 118 Ryan
-------------
Height Name Grade
0 120 Tom 3
1 110 jerry 1
2 125 Alexander 2
3 122 Jack 1
4 119 Aiden 3
5 118 Ryan 2
3.替代值replace()
:
replace()
方法可以对原数据中的某个值进行替代,也可以一次替代多个值(传入原值列表),也可以将不同的值替代为不同的值(传入替代值列表)。
data = pd.Series([25,999,36,56,999,58,1000])
print(data)
print('-------------')
print(data.replace(1000,np.nan))
print('-------------')
print(data.replace([999,1000],np.nan))
print('-------------')
print(data.replace({999:np.nan,1000:0}))
print('-------------')
0 25
1 999
2 36
3 56
4 999
5 58
6 1000
dtype: int64
-------------
0 25.0
1 999.0
2 36.0
3 56.0
4 999.0
5 58.0
6 NaN
dtype: float64
-------------
0 25.0
1 NaN
2 36.0
3 56.0
4 NaN
5 58.0
6 NaN
dtype: float64
-------------
0 25.0
1 NaN
2 36.0
3 56.0
4 NaN
5 58.0
6 0.0
dtype: float64
-------------
4.重命名轴索引:
通过赋值给原来数据的index,进行轴索引的重命名操作。
df = pd.DataFrame({'Name':['Tom','jerry','Alexander','Jack','Aiden','Ryan'],'Height':[120,110,125,122,119,118]},index=[3,1,2,1,3,2])
print(df)
print('---------')
Grade = {3:'Grade3',1:'Grade1',2:'Grade2',1:'Grade1',3:'Grade3',2:'Grade2'}
df.index = df.index.map(lambda x:Grade[x])
print(df)
Height Name
3 120 Tom
1 110 jerry
2 125 Alexander
1 122 Jack
3 119 Aiden
2 118 Ryan
---------
Height Name
Grade3 120 Tom
Grade1 110 jerry
Grade2 125 Alexander
Grade1 122 Jack
Grade3 119 Aiden
Grade2 118 Ryan
如果创建数据集转换后的版本,并且不修改原有的数据集,可以使用rename()
方法。
print(df.rename(index=str,columns=str.upper))
```
HEIGHT NAME
Grade3 120 Tom
Grade1 110 jerry
Grade2 125 Alexander
Grade1 122 Jack
Grade3 119 Aiden
Grade2 118 Ryan
rename()
方法可以结合字典对象使用,为轴提供新值。
print(df.rename(index={'Grade3':'三年级'},columns={'Name':'名字','Height':'身高'}))
身高 名字
三年级 120 Tom
Grade1 110 jerry
Grade2 125 Alexander
Grade1 122 Jack
三年级 119 Aiden
Grade2 118 Ryan
5.离散化与分箱:
在日常的数据分析处理工作中,连续性数据经常需要做离散化或者分箱处理。
cut()
方法
例如把年龄分成n组。
# 将年龄按照18~25,26~35,36~60,60~100分组
ages = [22,21,25,28,21,23,36,33,65,46,40,39]
bins = [18,25,35,60,100]
ages_cate = pd.cut(ages,bins)
print(ages_cate)
print('---------')
print(ages_cate.codes)
print('---------')
print(ages_cate.categories)
print('---------')
print(pd.value_counts(ages_cate)) # 对cut结果中的分组数量的计数
pd.cut()
方法返回的是一个特殊的Categorical对象。
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (35, 60]]
Length: 12
Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
---------
[0 0 0 1 0 0 2 1 3 2 2 2]
---------
IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]]
closed='right',
dtype='interval[int64]')
---------
(18, 25] 5
(35, 60] 4
(25, 35] 2
(60, 100] 1
dtype: int64
默认情况下,区间的左边为封闭的、右边为开放的,可以通过传递right=False
改变区间。
ages = [22,21,25,28,21,23,36,33,65,46,40,39]
bins = [18,25,35,60,100]
ages_cate = pd.cut(ages,bins)
print(ages_cate)
print('---------')
ages_cate2 = pd.cut(ages,bins,right=False)
print(ages_cate2)
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (35, 60]]
Length: 12
Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
---------
[[18, 25), [18, 25), [25, 35), [25, 35), [18, 25), ..., [25, 35), [60, 100), [35, 60), [35, 60), [35, 60)]
Length: 12
Categories (4, interval[int64]): [[18, 25) < [25, 35) < [35, 60) < [60, 100)]
还可以通过向labels
选项传递一个列表或数组来自定义箱名。
ages = [22,21,25,28,21,23,36,33,65,46,40,39]
bins = [18,25,35,60,100]
group_names =['未成年','成年','中年','老年']
ages_cate = pd.cut(ages,bins,labels=group_names)
print(ages_cate)
[未成年, 未成年, 未成年, 成年, 未成年, ..., 成年, 老年, 中年, 中年, 中年]
Length: 12
Categories (4, object): [未成年 < 成年 < 中年 < 老年]
也可以传入希望切分的数量,系统会根据最大值和最小值自动计算出等长的箱,其中precision
选项用于设置精度限制。
ages = [22,21,25,28,21,23,36,33,65,46,40,39]
ages_cate = pd.cut(ages,4,precision=2)
print(ages_cate)
[(20.96, 32.0], (20.96, 32.0], (20.96, 32.0], (20.96, 32.0], (20.96, 32.0], ..., (32.0, 43.0], (54.0, 65.0], (43.0, 54.0], (32.0, 43.0], (32.0, 43.0]]
Length: 12
Categories (4, interval[float64]): [(20.96, 32.0] < (32.0, 43.0] < (43.0, 54.0] < (54.0, 65.0]]
qcut()
方法
qcut()
方法是一个与分箱操作密切相关的函数,是基于样本分位数进行分箱操作。由于是基于样本分位数进行分箱,所以通常不会使得每个箱中具有相同数量的样本点。由于qcut()
方法使用样本分位数,可以获得等长的箱。当然也可以传入自定义的分位数。
data = np.random.randn(100)
data_cate = pd.qcut(data,4) # 切分成四份
print(data_cate)
print('------------------')
print(pd.value_counts(data_cate))
print('------------------')
print(pd.qcut(data,[0,0.1,0.5,0.9,1]))
[(-0.63, 0.146], (0.646, 2.382], (-2.3089999999999997, -0.63], (-2.3089999999999997, -0.63], (0.146, 0.646], ..., (0.146, 0.646], (0.146, 0.646], (-2.3089999999999997, -0.63], (-0.63, 0.146], (0.646, 2.382]]
Length: 100
Categories (4, interval[float64]): [(-2.3089999999999997, -0.63] < (-0.63, 0.146] < (0.146, 0.646] < (0.646, 2.382]]
------------------
(0.646, 2.382] 25
(0.146, 0.646] 25
(-0.63, 0.146] 25
(-2.3089999999999997, -0.63] 25
dtype: int64
------------------
[(-1.045, 0.146], (0.146, 1.194], (-1.045, 0.146], (-1.045, 0.146], (0.146, 1.194], ..., (0.146, 1.194], (0.146, 1.194], (-2.3089999999999997, -1.045], (-1.045, 0.146], (1.194, 2.382]]
Length: 100
Categories (4, interval[float64]): [(-2.3089999999999997, -1.045] < (-1.045, 0.146] < (0.146, 1.194] < (1.194, 2.382]]
6.置换和随机抽样:
df = pd.DataFrame(np.arange(24).reshape(6,4))
print(df)
print('---------')
# 生成一个随机数列
sampler = np.random.permutation(6)
print(sampler)
print('---------')
# 使用生成的随机数列对原数据进行重新排序
print(df.take(sampler))
print('---------')
# 随机选择n行数据
print(df.sample(n=3))
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 12 13 14 15
4 16 17 18 19
5 20 21 22 23
---------
[4 2 1 5 3 0]
---------
0 1 2 3
4 16 17 18 19
2 8 9 10 11
1 4 5 6 7
5 20 21 22 23
3 12 13 14 15
0 0 1 2 3
---------
0 1 2 3
0 0 1 2 3
1 4 5 6 7
3 12 13 14 15
Reference:
《Python for Data Analysis:Data Wrangling with Pandas,Numpy,and IPython》