一:删除重复元素
二:映射
三:使用聚合操作对数据异常值检测和过滤
四:排序
五:数据分类处理 [重点]
六:高级数据聚合
一:删除重复元素
使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True
- keep参数:指定保留哪一重复的行数据
import numpy as np
from pandas import DataFrame,Series
import pandas as pd
#创建具有重复元素行的DataFrame
#创建一个df
df = DataFrame(data=np.random.randint(0,100,size=(9,5)))
df.iloc[1] = [6,6,6,6,6]
df.iloc[3] = [6,6,6,6,6]
df.iloc[5] = [6,6,6,6,6]
df
0 1 2 3 4
0 95 45 44 19 97
1 6 6 6 6 6
2 80 31 49 27 7
3 6 6 6 6 6
4 70 5 58 20 48
5 6 6 6 6 6
6 88 47 31 63 39
7 8 52 96 8 51
8 14 83 42 3 33
使用drop_duplicates()函数删除重复的行
- drop_duplicates(keep='first/last'/False)
df.drop_duplicates(keep='first')
0 1 2 3 4
0 95 45 44 19 97
1 6 6 6 6 6
2 80 31 49 27 7
4 70 5 58 20 48
6 88 47 31 63 39
7 8 52 96 8 51
8 14 83 42 3 33
二:映射
1) replace()函数:替换元素
DataFrame替换操作
单值替换
普通替换: 替换所有符合要求的元素:to_replace=15,value='e'
按列指定单值替换: to_replace={列标签:替换值} value='value'
多值替换
列表替换: to_replace=[] value=[]
字典替换(推荐) to_replace={to_replace:value,to_replace:value}
# 1
df.replace(to_replace=6,value='six')
0 1 2 3 4
0 95 45 44 19 97
1 six six six six six
2 80 31 49 27 7
3 six six six six six
4 70 5 58 20 48
5 six six six six six
6 88 47 31 63 39
7 8 52 96 8 51
8 14 83 42 3 33
# 2
df.replace(to_replace={3:'three'})
0 1 2 3 4
0 95 45 44 19 97
1 6 6 6 6 6
2 80 31 49 27 7
3 6 6 6 6 6
4 70 5 58 20 48
5 6 6 6 6 6
6 88 47 31 63 39
7 8 52 96 8 51
8 14 83 42 three 33
# 3
df.replace(to_replace={3:6},value='six')
0 1 2 3 4
0 95 45 44 19 97
1 6 6 6 six 6
2 80 31 49 27 7
3 6 6 6 six 6
4 70 5 58 20 48
5 6 6 6 six 6
6 88 47 31 63 39
7 8 52 96 8 51
8 14 83 42 3 33
2) map()函数:新建一列 , map函数并不是df的方法,而是series的方法
map()可以映射新一列数据
map()中可以使用lambd表达式
map()中可以使用方法,可以是自定义的方法
eg:map({to_replace:value})
注意 map()中不能使用sum之类的函数,for循环
# - 新增一列:给df中,添加一列,该列的值为中文名对应的英文名
dic = {
'name':['jay','tom','jay'],
'salary':[9999,5000,9999]
}
df = DataFrame(data=dic)
df
name salary
0 jay 9999
1 tom 5000
2 jay 9999
dic = {
'jay':'周杰伦',
'tom':'张三'
}
df['c_name'] = df['name'].map(dic)
df
name salary c_name
0 jay 9999 周杰伦
1 tom 5000 张三
2 jay 9999 周杰伦
# map当做一种运算工具,至于执行何种运算,是由map函数的参数决定的(参数:lambda,函数)¶
# 使用自定义函数
def after_sal(s):
return s - (s-5000)*0.5
#超过3000部分的钱缴纳50%的税
df['after_sal'] = df['salary'].map(after_sal)
df
name salary c_name after_sal
0 jay 9999 周杰伦 7499.5
1 tom 5000 张三 5000.0
2 jay 9999 周杰伦 7499.5
df['salary'].apply(after_sal)
0 7499.5
1 5000.0
2 7499.5
Name: salary, dtype: float64
### 注意:并不是任何形式的函数都可以作为map的参数。只有当一个函数具有一个参数且有返回值,那么该函数才可以作为map的参数。
三:使用聚合操作对数据异常值检测和过滤
使用df.std()函数可以求得DataFrame对象每一列的标准差
- 创建一个1000行3列的df 范围(0-1),求其每一列的标准差
df = DataFrame(data=np.random.random(size=(1000,3)),columns=['A','B','C'])
df.head()
A B C
0 0.421703 0.113982 0.378142
1 0.135788 0.202773 0.556716
2 0.026390 0.869824 0.780703
3 0.267029 0.302224 0.544516
4 0.404328 0.367307 0.035302
# 对df应用筛选条件,去除标准差太大的数据:假设过滤条件为 C列数据大于两倍的C列标准差
std_twice = df['C'].std() * 2
std_twice # 0.5809347094044642
df['C'] > std_twice
#异常值对应的行数据
df.loc[df['C'] > std_twice]
indexs = df.loc[df['C'] > std_twice].index
df.drop(labels=indexs,axis=0,inplace=True)
- 数据清洗
- 清洗空值
- dropna fillna isnull notnull any all
- 清洗重复值
- drop_duplicates(keep)
- 清洗异常值
- 异常值监测的结果(布尔值),作为清洗的过滤的条件
四:排序
使用.take()函数排序
- take()函数接受一个索引列表,用数字表示,使得df根据列表中索引的顺序进行排序
- eg:df.take([1,3,4,2,5])
可以借助np.random.permutation()函数随机排序
df.take([2,1,0],axis=1).take(np.random.permutation(500),axis=0)
#随机取20行
df.take([2,1,0],axis=1).take(np.random.permutation(500),axis=0)[0:20]
- np.random.permutation(x)可以生成x个从0-(x-1)的随机数列
# 随机抽样
当DataFrame规模足够大时,直接使用np.random.permutation(x)函数,就配合take()函数实现随机抽样
五:数据分类处理 [重点]
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
数据分类处理:
- 分组:先把数据分为几组
- 用函数处理:为不同组的数据应用不同的函数以转换数据
- 合并:把不同组得到的结果合并起来
数据分类处理的核心:
- groupby()函数
- groups属性查看分组情况
- eg: df.groupby(by='item').groups
# 分组
from pandas import DataFrame,Series
df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'],
'price':[4,3,3,2.5,4,2],
'color':['red','yellow','yellow','green','green','green'],
'weight':[12,20,50,30,20,44]})
df
item price color weight
0 Apple 4.0 red 12
1 Banana 3.0 yellow 20
2 Orange 3.0 yellow 50
3 Banana 2.5 green 30
4 Orange 4.0 green 20
5 Apple 2.0 green 44
# - 使用groupby实现分组
df.groupby(by='item')
# <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000023E4349CCC0>
# - 使用groups查看分组情况
# 该函数可以进行数据的分组,但是不显示分组情况
df.groupby(by='item').groups
{'Apple': Int64Index([0, 5], dtype='int64'),
'Banana': Int64Index([1, 3], dtype='int64'),
'Orange': Int64Index([2, 4], dtype='int64')}
# 给df创建一个新列,内容为各个水果的平均价格
# 1 这是错误的 这个方法不太好
df.groupby(by='item').mean()['price']
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64
# 2 这是正确的 把 .mean() 放后面,先找到后计算
mean_price_s = df.groupby(by='item')['price'].mean()
mean_price_s
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64
# 3
dic = mean_price_s.to_dict()
dic
# {'Apple': 3.0, 'Banana': 2.75, 'Orange': 3.5}
# 4
df['mean_price'] = df['item'].map(dic)
df
item price color weight mean_price
0 Apple 4.0 red 12 3.00
1 Banana 3.0 yellow 20 2.75
2 Orange 3.0 yellow 50 3.50
3 Banana 2.5 green 30 2.75
4 Orange 4.0 green 20 3.50
5 Apple 2.0 green 44 3.00
六:高级数据聚合
使用groupby分组后,也可以使用transform和apply提供自定义函数实现更多的运算
- df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
- transform和apply都会进行运算,在transform或者apply中传入函数即可
- transform和apply也可以传入一个lambda表达式
def my_mean(s):
sum = 0
for i in s:
sum += i
return sum/s.size
df.groupby(by='item')['price'].transform(my_mean)
0 3.00
1 2.75
2 3.50
3 2.75
4 3.50
5 3.00
Name: price, dtype: float64
df.groupby(by='item')['price'].apply(my_mean)
item
Apple 3.00
Banana 2.75
Orange 3.50
Name: price, dtype: float64