0%

Python之Pandas库躺坑记

背景

​ 最近在开发一个线上用例管理平台,需要使用 Python语言Excel文件 进行一系列的操作,网上大致搜索了下常用的库,最后决定使用 Pandas 库(原因就不具体阐述了)。在使用的过程中,大部分的需求都能满足,但是还是有部分需求通过不断躺坑最终解决了。

Pandas 库常用的方法就不一一阐述了,可以参考如下链接。

在此将整个过程中遇到的一些特定的问题进行记录┑( ̄。。 ̄)┍ ┑( ̄。。 ̄)┍ 。

特殊问题

问题1. 部分Excel文件单元格进行了合并或者单元格内容为空

需要对合并了的单元格或者单元格内容为空的进行内容,通过Debug发现此时值为 Nan

解决办法:

1
2
3
4
# 将单元格的值赋值给data
data = df.iloc[iRow, iCol]
# 通过如下方法判断 data 是否为 Nan, 是则返回 True。
isinstance(data, float) and math.isnan(df.iloc[iRow, iCol])

问题2. 使用Panads的to_excel方法会覆盖其他所有的sheet

具体问题:在使用pandas的 df.to_excel(file_path) 想要对一个有多张sheet的workbook操作时一定会尴尬的发现:永远只存在最后一次写进去的表,其他的sheet表都被清空了,并且最后一次写进去的表的样式也未保存。

解决办法: 参考链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import openpyxl 
import pandas as pd

# file_abs_path excel文件的绝对路径
excel_sheet_handle = pd.read_excel(file_abs_path, sheet_name="sheet1")
# ... 中间对 sheet1 进行一系列值的改动

# 通过下方的代码将其他 sheet 的内容与最新的 sheet1 表进行合并。
book = openpyxl.load_workbook(file_abs_path)
writer = pd.ExcelWriter(file_abs_path, engine='openpyxl')
writer.book = book

writer.sheets = dict((ws.title, ws) for ws in book.worksheets)
# index 为序号, header 为原来的表头
excel_sheet_handle.to_excel(writer, sheet_name="sheet1", index=False, header=True)

通过如上的办法就可以将所有表都保存下来,并且保存了原有的样式, sheet1表的内容也修改正确。

问题3. 使用了问题2的办法后,使用Panads.drop()方法在最后出现重复行。

1
2
3
4
# file_abs_path excel文件的绝对路径
excel_sheet_handle = pd.read_excel(file_abs_path, sheet_name="sheet1")
# 将文件的第2、3行删除掉
excel_sheet_handle.drop([1, 2], inplace=True)

具体问题现象如下:存在文件A,里面的sheet1表中有4行数据(如下),通过上述代码的drop删除后, 再调用问题2中的办法进行保存,发现sheet1表中仍然有4行, 内容为原来的第1、4、3、4 行内容,实际预期应该只是第1、4行的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# excel_sheet_handle.drop([1, 2], inplace=True)
# 原数据
A B C D
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 3 2 6 7

# 预期应该为:
A B C D
0 0 1 2 3
3 3 2 6 7

# 实际结果为:
A B C D
0 0 1 2 3
3 3 2 6 7
2 8 9 10 11
3 3 2 6 7

具体原因: 由于问题2中进行了原来的sheet内容读取,所以在writer中也记录了原来的 sheet1 的内容,导致 writer 在写入的时候又重新将原来的第3、4行与实际的 第1、4行进行了合并。

最终解决办法(根据上述的实例):

1
2
3
4
5
6
7
8
9
max_row = 4
# 共删除了2、3两行,所以删除的行数为2
delete_row_count = 2
change_sheet = writer.sheets["sheet1"]
# 删除原来重复合并的第 3、4行。
change_sheet.delete_rows(3, 4)

writer.save()
writer.close()

问题4. 在指定行插入一行数据

具体需求:可能需要通过在不同的行插入指定的数据,比如,sheet表中共10行,需要在第5行插入一条数据。

解决办法参考链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 可以先将表格分开,添加行后再合并,原数据如下, 在第1行(猫之前)插入 羊,数量9, 
# 动物 数量
# 0 狗 3
# 1 猫 4
# 2 兔 6

具体实现代码如下
df1 = df.loc[:0]
df2 = df.loc[1:]
print('df1 is:\n', df1)
print('df2 is:\n', df2)
df3 = pd.DataFrame({'动物' : ['羊'], '数量' : [ 9 ]})
df = df1.append(df3, ignore_index = True).append(df2, ignore_index = True)
print(df)
# df1 is:
# 动物 数量
# 0 狗 3

# df2 is:
# 动物 数量
# 1 猫 4
# 2 兔 6

# 动物 数量
# 0 狗 3
# 1 羊 9
# 2 猫 4
# 3 兔 6

总结

​ 只有真的多面对几次现实中的需求,才能真的掌握一个库的使用。。。否则仅仅是最基础的 Demo 演练。

------------- 本 文 结 束 感 谢 您 的 阅 读 -------------