转载自 https://blog.csdn.net/lijinlon/article/details/81517699
Data analysis by Python 入门
1. 重复数据处理
在DataFrame中主要运用duplicated方法和drop_duplicates方法:
- duplicated方法返回的是一个布尔型的Series,用来只是各行是否重复,如果重复则为True,否则为False。
- drop_duplicates直接返回已经删除了重复行的DataFrame。
默认drop_duplicates方法会判断所有列,只有所有列的值都重复才算重复行,如果仅需要依据某一列或者某几列进行重复项判断。可以添加列名的列表:drop_duplicates([‘K1’])或者drop_duplicates([‘K1’,’K2’])。删除的重复值可以选择保留第一项还是最后一项,添加 keep = ‘last’,会保留最后一个重复值,keep = ‘first’会保留第一个重复值。
1.1 Excel文件读取
pandas的ExcelFile类或pandas.read_excel函数支持读取存储在Excel 2003(或更高版本)中的表格型数据。这两个工具分别使用扩展包xlrd和openpyxl读取XLS和XLSX文件。你可以用pip或conda安装它们。
要使用ExcelFile,通过传递xls或xlsx路径创建一个实例,然后用存储在表单中的数据可以read_excel读取到DataFrame
import pandas as pd
xlsx = pd.ExcelFile('H:/DataAnalysis/data/ch04/4.2/重复数据处理.xls')
frame = pd.read_excel(xlsx, 'Sheet1')
frame
# 也可以直接用read_excel读取
# frame = pd.read_excel('H:/DataAnalysis/data/ch04/4.2/重复数据处理.xls', 'Sheet1')
|
编号 |
0 |
A667708 |
1 |
A310882 |
2 |
A356517 |
3 |
A520304 |
4 |
A776477 |
5 |
A466074 |
6 |
A466074 |
7 |
A466074 |
8 |
A776477 |
9 |
A218912 |
1.2 重复数据处理
使用DataFrame的drop_duplicates()进行重复数据的删除
frame_ = frame.drop_duplicates(keep = 'last')
# keep = 'last',会保留最后一个重复值,keep = 'first'会保留第一个重复值
frame_
|
编号 |
0 |
A667708 |
1 |
A310882 |
2 |
A356517 |
3 |
A520304 |
7 |
A466074 |
8 |
A776477 |
9 |
A218912 |
处理数据另存为Excel文件
如果要将pandas数据写入为Excel格式,你必须首先创建一个ExcelWriter,然后使用pandas对象的to_excel方法将 数据写入到其中:
writer = pd.ExcelWriter('H:/DataAnalysis/data/ch04/4.2/重复数据处理_处理后.xls')
frame_.to_excel(writer, 'Sheet1')
writer.save()
# 当然,你还可以不使用ExcelWriter,而是传递文件的路径到to_excel:
# frame.to_excel('H:/DataAnalysis/data/ch04/4.2/重复数据处理_处理后.xls')
2. 检查数据逻辑错误
逻辑错误是根据数据来源、数据性质等进行判断的,比如年龄出现负值等等。
这里的例子是在多选题中需要选择3项,为0代表未选择,不为0代表选择,所以需要判断每一行数据中不为0的个数是否等于3.
因为原先的xls文件有合并单元格,首先手动将其删除,只留下标题列ABCDEFG和表内容。
frame2 = pd.read_excel('H:/DataAnalysis/data/ch04/4.2/检查数据逻辑错误.xls', 'Sheet1')
frame2_ = frame2.copy()
frame2_
|
A |
B |
C |
D |
E |
F |
G |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
2 |
1 |
0 |
1 |
0 |
2 |
0 |
0 |
3 |
1 |
10 |
1 |
0 |
0 |
0 |
0 |
# DataFrame的loc和iloc方法可以选中行进行计算判断,loc和iloc分别通过索引和整数索引进行选择
for i in range(len(frame2_)):
if (frame2_.loc[i] !=0).sum() == 3:
frame2_.loc[i, '校验'] = '正确'
else:
frame2_.loc[i, '校验'] = '错误'
frame2_
|
A |
B |
C |
D |
E |
F |
G |
校验 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
正确 |
1 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
错误 |
2 |
1 |
0 |
1 |
0 |
2 |
0 |
0 |
错误 |
3 |
1 |
10 |
1 |
0 |
0 |
0 |
0 |
错误 |
3. 字段分列(带分隔符)
在数据源数据中,有时根据需要,需要从某一列数据中提取信息(比如从身份证号中提取出生年月信息)或者对数据进行分割(比如类似2011-01-05的日期,提取年月日信息单独成列)。根据数据的不同分为两种情况,利用字符串的分隔提取方法解决:
- 需要分列的信息之间有特殊的分隔符,比如逗号、空格等,可以直接用split方法分割;
- 没有特殊分隔符时,采用对字符串的索引方式,如 对x = ‘spam’;可以使用x[0],x[-1],x[1:3]等进行信息提取
本例是针对英文名进行分割,中间有空格作为分隔符
excel文件比较随意,只添加了数据内容,没有列名,先手动添加列名 name
frame3 = pd.read_excel('H:/DataAnalysis/data/ch04/4.3/字段分列.xls', 'Sheet1')
frame3
|
name |
0 |
Syed Abbas |
1 |
Molly Dempsey |
2 |
Lola Jacobsen |
3 |
Diane Margheim |
# 首先提取需要分裂的列,用split()分列,显然,这里的分隔符为空格
frame3_ = pd.DataFrame((x.split(' ') for x in frame3.name), index = frame3.index, columns = ['A', 'B'])
frame3_
|
A |
B |
0 |
Syed |
Abbas |
1 |
Molly |
Dempsey |
2 |
Lola |
Jacobsen |
3 |
Diane |
Margheim |
4. 字段分列(无特定分隔符)
frame4 = pd.read_excel('H:/DataAnalysis/data/ch04/4.3/数据抽取.xls', 'Sheet1')
frame4
|
姓名 |
姓 |
0 |
黄雅玲 |
NaN |
1 |
王伟 |
NaN |
2 |
谢丽秋 |
NaN |
3 |
王俊元 |
NaN |
4 |
孙林 |
NaN |
5 |
王炫皓 |
NaN |
6 |
张三丰 |
NaN |
7 |
李四光 |
NaN |
8 |
王麻子 |
NaN |
9 |
赵六儿 |
NaN |
# 字段本质上为字符串,固定的位置可以直接用索引直接选取
frame4['姓'] = pd.Series((x[0]) for x in frame4['姓名'])
frame4
|
姓名 |
姓 |
0 |
黄雅玲 |
黄 |
1 |
王伟 |
王 |
2 |
谢丽秋 |
谢 |
3 |
王俊元 |
王 |
4 |
孙林 |
孙 |
5 |
王炫皓 |
王 |
6 |
张三丰 |
张 |
7 |
李四光 |
李 |
8 |
王麻子 |
王 |
9 |
赵六儿 |
赵 |
5. 字段匹配
在excel中,vlookup是字段匹配搜索的神器,加上INDEX和MATCH函数几乎所向披靡。在DataFrame中,merge是合并两个DataFrame的方法,可以利用on = ‘列名’选择该列进行匹配,还可以选择选择交集、并集、左合并、右合并,功能十分强大
在本例中,员工职位表中有员工的姓名、工号、职务等信息,而在员工个人信息表中缺少职务信息,需要从员工职位表中将职务信息对应添加到员工个人信息表中。选择工号列进行匹配。
frame51 = pd.read_excel('H:/DataAnalysis/data/ch04/4.3/字符匹配/员工职位表.xlsx', 'Sheet1')
frame51
|
姓名 |
工号 |
部门 |
职务 |
0 |
黄雅玲 |
A776477 |
销售部 |
销售代表 |
1 |
王伟 |
A667708 |
销售部 |
销售代表 |
2 |
谢丽秋 |
A520304 |
销售部 |
销售代表 |
3 |
王俊元 |
A310882 |
销售部 |
销售总监 |
4 |
孙林 |
A466074 |
销售部 |
销售代表 |
5 |
王炫皓 |
A356517 |
销售部 |
销售代表 |
6 |
张三丰 |
A277381 |
市场部 |
市场总监 |
7 |
李四光 |
A254382 |
市场部 |
市场助理 |
8 |
王麻子 |
A213541 |
市场部 |
市场助理 |
9 |
赵六儿 |
A309752 |
市场部 |
市场助理 |
frame52 = pd.read_excel('H:/DataAnalysis/data/ch04/4.3/字符匹配/员工个人信息表(销售部).xlsx', 'Sheet1')
frame52
|
姓名 |
工号 |
出生年月 |
性别 |
工龄 |
职务 |
0 |
黄雅玲 |
A776477 |
12/8/1968 |
女 |
37 |
NaN |
1 |
王俊元 |
A310882 |
2/19/1952 |
男 |
45 |
NaN |
2 |
谢丽秋 |
A520304 |
8/30/1963 |
女 |
28 |
NaN |
3 |
王炫皓 |
A356517 |
9/19/1958 |
男 |
33 |
NaN |
4 |
孙林 |
A466074 |
3/4/1955 |
男 |
29 |
NaN |
5 |
王伟 |
A667708 |
7/2/1963 |
男 |
8 |
NaN |
# 需要从《员工职位表》中提取‘职务’信息到《员工个人信息表》中,这相当于两个DataFrame合并,连接键为‘工号’,需要的字段为职务
pd.merge(frame52, frame51[['工号', '职务']], on = '工号')
|
姓名 |
工号 |
出生年月 |
性别 |
工龄 |
职务_x |
职务_y |
0 |
黄雅玲 |
A776477 |
12/8/1968 |
女 |
37 |
NaN |
销售代表 |
1 |
王俊元 |
A310882 |
2/19/1952 |
男 |
45 |
NaN |
销售总监 |
2 |
谢丽秋 |
A520304 |
8/30/1963 |
女 |
28 |
NaN |
销售代表 |
3 |
王炫皓 |
A356517 |
9/19/1958 |
男 |
33 |
NaN |
销售代表 |
4 |
孙林 |
A466074 |
3/4/1955 |
男 |
29 |
NaN |
销售代表 |
5 |
王伟 |
A667708 |
7/2/1963 |
男 |
8 |
NaN |
销售代表 |
6. 简单计算
本质上相当于在DataFrame添加一列,该列由前面列的数据生成,直接两列相乘即可
本例中是计算销售额(运用公式:销售额 = 销售数量 * 单价)
frame6 = pd.read_excel('H:/DataAnalysis/data/ch04/4.3/简单计算.xls', 'Sheet1')
frame6
|
产品名称 |
销售数量 |
单价 |
销售额 |
0 |
产品A |
200.0 |
78.0 |
NaN |
1 |
产品B |
300.0 |
88.0 |
NaN |
2 |
产品C |
100.0 |
85.0 |
NaN |
3 |
产品D |
50.0 |
100.0 |
NaN |
4 |
产品E |
87.0 |
68.0 |
NaN |
5 |
合计 |
NaN |
NaN |
NaN |
frame6['销售额'] = frame6['销售数量'] * frame6['单价']
frame6
|
产品名称 |
销售数量 |
单价 |
销售额 |
0 |
产品A |
200.0 |
78.0 |
15600.0 |
1 |
产品B |
300.0 |
88.0 |
26400.0 |
2 |
产品C |
100.0 |
85.0 |
8500.0 |
3 |
产品D |
50.0 |
100.0 |
5000.0 |
4 |
产品E |
87.0 |
68.0 |
5916.0 |
5 |
合计 |
NaN |
NaN |
NaN |
# 这里销售额已经计算完毕,因为看到表格中还有合计项,顺便联系一下iloc的用法
frame6.iloc[5, 1:] = frame6.iloc[0:5, 1:].sum()
frame6
|
产品名称 |
销售数量 |
单价 |
销售额 |
0 |
产品A |
200.0 |
78.0 |
15600.0 |
1 |
产品B |
300.0 |
88.0 |
26400.0 |
2 |
产品C |
100.0 |
85.0 |
8500.0 |
3 |
产品D |
50.0 |
100.0 |
5000.0 |
4 |
产品E |
87.0 |
68.0 |
5916.0 |
5 |
合计 |
737.0 |
419.0 |
61416.0 |
7. 函数计算
计算平均值和总和直接使用mean和sum函数,因为是计算每行的值,需要设置axis=1。
frame7 = pd.read_excel('H:/DataAnalysis/data/ch04/4.3/函数计算.xls', 'Sheet1')
frame7
|
产品名称 |
一季度 |
二季度 |
三季度 |
四季度 |
季度平均 |
总销售量 |
0 |
产品A |
51.00 |
40.8 |
56.100 |
91.80 |
NaN |
NaN |
1 |
产品B |
20.00 |
16.0 |
22.000 |
36.00 |
NaN |
NaN |
2 |
产品C |
154.00 |
123.2 |
169.400 |
277.20 |
NaN |
NaN |
3 |
产品D |
60.00 |
48.0 |
66.000 |
108.00 |
NaN |
NaN |
4 |
产品E |
96.00 |
76.8 |
105.600 |
172.80 |
NaN |
NaN |
5 |
产品F |
95.25 |
76.2 |
104.775 |
171.45 |
NaN |
NaN |
frame7['季度平均'] = frame7[['一季度', '二季度', '三季度', '四季度']].mean(axis = 1)
frame7['总销售量'] = frame7[['一季度','二季度','三季度','四季度']].sum(axis = 1)
frame7
|
产品名称 |
一季度 |
二季度 |
三季度 |
四季度 |
季度平均 |
总销售量 |
0 |
产品A |
51.00 |
40.8 |
56.100 |
91.80 |
59.92500 |
239.700 |
1 |
产品B |
20.00 |
16.0 |
22.000 |
36.00 |
23.50000 |
94.000 |
2 |
产品C |
154.00 |
123.2 |
169.400 |
277.20 |
180.95000 |
723.800 |
3 |
产品D |
60.00 |
48.0 |
66.000 |
108.00 |
70.50000 |
282.000 |
4 |
产品E |
96.00 |
76.8 |
105.600 |
172.80 |
112.80000 |
451.200 |
5 |
产品F |
95.25 |
76.2 |
104.775 |
171.45 |
111.91875 |
447.675 |