3.2 处理单个工作表
尽管 Excel 工作簿可以包含多个工作表,有些时候你也只是需要一个工作表中的数据。此外,只要你知道如何分析一个工作表,就可以很容易地扩展到分析多个工作表。
3.2.1 读写Excel文件
基础Python和xlrd、xlwt模块
要使用基础 Python 和 xlrd、xlwt 模块读写 Excel 文件,在文本编辑器中输入下列代码,然后将文件保存为 2excel_parsing_and_write.py:
1 #!/usr/bin/env python3 2 import sys 3 from xlrd import open_workbook 4 from xlwt import Workbook 5 input_file = sys.argv[1] 6 output_file = sys.argv[2] 7 output_workbook = Workbook() 8 output_worksheet = output_workbook.add_sheet('jan_2013_output') 9 with open_workbook(input_file) as workbook: 10 worksheet = workbook.sheet_by_name('january_2013') 11 for row_index in range(worksheet.nrows): 12 for column_index in range(worksheet.ncols): 13 output_worksheet.write(row_index, column_index, \ 14 worksheet.cell_value(row_index, column_index)) 15 output_workbook.save(output_file)
第 3 行代码导入 xlrd 模块的 open_workbook 函数,第 4 行代码导入 xlwt 模块的 Workbook 对象。
第 7 行代码实例化一个 xlwt Workbook 对象,以使我们可以将结果写入用于输出的 Excel 文件。第 8 行代码使用 xlwt 的 add_sheet 函数为输出工作簿添加一个工作表 jan_2013_output。
第 9 行代码使用 xlrd 的 open_workbook 函数打开用于输入的工作簿,并将结果赋给一个 workbook 对象。第 10 行代码使用这个 workbook 对象的 sheet_by_name 函数引用名称为 january_2013 的工作表。
第 11~12 行代码创建了行与列索引值上的 for 循环语句,使用 range 函数和 worksheet 对象的 nrows 属性和 ncols 属性,在工作表的每行和每列之间迭代。
第 13 行代码使用 xlwt 的 write 函数和行与列的索引将每个单元格的值写入输出文件的工作表。
最后,第 15 行代码保存并关闭输出工作簿。
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python 2excel_parsing_and_write.py sales_2013.xlsx output_files\2output.xls
你可以打开输出文件 2output.xls 查看一下结果。
你可能已经发现,Purchase Date 列(也就是第 E 列)中的日期显示为数值,不是日期。Excel 将日期和时间保存为浮点数,这个浮点数代表从 1900 年 1 月 0 日开始经过的日期数,加上一个 24 小时的小数部分。例如,数值 1 代表 1900 年 1 月 1 日,因为从 1900 年 1 月 0 日过去了 1 天。因此,这一列中的数值代表日期,但是没有格式化为日期的形式。
xlrd 扩展包提供了其他函数来格式化日期值。下一个示例通过演示如何格式化日期数据修正了前一个示例,这样日期值就可以像在输入文件中一样打印到屏幕上或写入输出文件了。
格式化日期数据。这个示例是基于前一个示例的,它展示了如何使用 xlrd 修改日期数据格式,使它们看上去和输入 Excel 文件中一样。例如,如果 Excel 工作表中的一个日期数据为 1/19/2000,那么我们通常希望将 1/19/2000 或其他相关日期格式写入输出文件。但是,就像前一个示例中那样,使用现在的示例代码,你会在输出文件中得到一个数值 36 544.0,因为这就是 1/0/1900 和 1/19/2000 之间的天数。
为了对日期列进行格式化,在文本编辑器中输入下列代码,然后将文件保存为 3excel_parsing_and_write_keep_dates.py:
1 #!/usr/bin/env python3 2 import sys 3 from datetime import date 4 from xlrd import open_workbook, xldate_as_tuple 5 from xlwt import Workbook 6 input_file = sys.argv[1] 7 output_file = sys.argv[2] 8 output_workbook = Workbook() 9 output_worksheet = output_workbook.add_sheet('jan_2013_output') 10 with open_workbook(input_file) as workbook: 11 worksheet = workbook.sheet_by_name('january_2013') 12 for row_index in range(worksheet.nrows): 13 row_list_output = [] 14 for col_index in range(worksheet.ncols): 15 if worksheet.cell_type(row_index, col_index) == 3: 16 date_cell = xldate_as_tuple(worksheet.cell_value\ 17 (row_index, col_index),workbook.datemode) 18 date_cell = date(*date_cell[0:3]).strftime\ 19 ('%m/%d/%Y') 20 row_list_output.append(date_cell) 21 output_worksheet.write(row_index, col_index, date_cell) 22 else: 23 non_date_cell = worksheet.cell_value\ 24 (row_index,col_index) 25 row_list_output.append(non_date_cell) 26 output_worksheet.write(row_index, col_index,\ 27 non_date_cell) 28 output_workbook.save(output_file)
第 3 行代码从 datetime 模块导入 date 函数,以使我们可以将数值转换成日期并对日期进行格式化。
第 4 行代码从 xlrd 模块中导入两个函数。在前面的示例中,是使用第一个函数打开的 Excel 工作簿,所以这里将重点介绍第二个函数。函数 xldate_as_tuple 可以将 Excel 中代表日期、时间或日期时间的数值转换为元组。只要将数值转换成了元组,就可以提取出具体时间元素(例如:年、月、日)并将时间元素格式化成不同的时间格式(例如: 1/1/2010 或 January 1, 2010)。
第 15 行代码创建了一个 if-else 语句来检验单元格类型是否为数字 3。如果你查看了 xlrd 模块的说明文档(https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html?p=4966#sheet.Cell-class),就会知道单元格类型为 3 表示这个单元格中包含日期数据。因此,if-else 语句检验每个单元格是否含有日期数据。如果含有日期数据,那么 if 代码块就对单元格进行处理;如果不含有日期数据,那么就使用 else 代码块对单元格进行处理。因为日期数据在最后一列,所以 if 代码块处理最后一列。
第 16 行代码使用 worksheet 对象的 cell_value 函数和行列索引来引用单元格中的值。此外,你还可以使用 cell().value 函数,这两个函数可以给出同样的结果。这个单元格中的值作为 xldate_as_tuple 函数中的第一个参数,会被转换成元组中的一个代表日期的浮点数。
参数 workbook.datemode 是必需的,它可以使函数确定日期是基于 1900 年还是基于 1904 年,并据此将数值转换成正确的元组(在 Mac 上的某些 Excel 版本从 1904 年 1 月 1 日开始计算日期。要获取这方面的更多信息,请阅读 Microsoft 参考指南(https://support.microsoft.com/en-us/kb/214330)。xldate_as_tuple 函数的结果被赋给一个元组变量 date_cell。这行代码太长了,所以被分为两行,第一行末尾字符是一个反斜杠(你应该记得在第 1 章中我们曾说过反斜杠是必需的,这样 Python 才能将这两行解释为一行)。尽管如此,在你自己的代码中,可以将所有代码都写在一行中而不使用反斜杠。
第 18 行代码使用元组索引来引用元组 date_cell 中的前 3 个元素(也就是年、月、日)并将它们作为参数传给 date 函数,这个函数可以将这些值转换成一个 date 对象,date 对象在第 1 章中曾介绍过。然后,strftime 函数将 date 对象转换为一个具有特定格式的字符串。格式 '%m/%d/%Y' 表示像 2014 年 3 月 15 日这样的日期应该显示为 03/15/2014。格式化后的日期字符串被重新赋给变量 date_cell。第 20 行代码使用列表的 append 函数将 date_cell 中的值追加给输出列表 row_list_output。
在运行了上面的脚本之后,为了对第 16 和 18 行代码中的操作有个大致概念,可以在两个 date_cell=…行之间添加一个 print 语句(也就是 print(date_cell))。重新保存并运行脚本,看一下 xldate_as_tuple 函数打印在屏幕上的结果。然后,删除这个 print 语句,将它移到第二个 date_cell=…语句下面。重新保存并运行脚本,看一下 date.strftime 函数打印在屏幕上的结果。这些 print 语句可以帮助你看到这两行中的函数是如何将 Excel 中代表日期的数值转换成一个元组,然后又转换成格式化的日期字符串的。
else 代码块处理所有的非日期单元格。第 23 行代码使用 worksheet 对象的 cell_value 函数和行列索引引用单元格中的值,并将其赋给变量 non_date_cell。第 25 行代码使用列表的 append 函数将 non_date_cell 中的值追加给 row_list_output。这两行代码提取出每行前四列中的值,并将它们追加到 row_list_output 中。
在行中的每一列都处理完成,并加入到 row_list_output 中之后,第 26 行代码将 row_list_output 中的值写入输出文件。
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python 3excel_parsing_and_write_keep_dates.py sales_2013.xlsx\ output_files\3output.xls
你可以打开输出文件 3output.xls 查看一下结果。
pandas。pandas 也有一组读取 Excel 文件的函数。下面是使用 pandas 分析 Excel 文件的示例代码。请将这段代码保存为 pandas_read_and_write_excel.py(此段代码读取 Excel 输入文件,将内容打印在屏幕上,然后将内容写入 Excel 输出文件):
#!/usr/bin/env python3 import pandas as pd import sys input_file = sys.argv[1] output_file = sys.argv[2] data_frame = pd.read_excel(input_file, sheetname='january_2013') writer = pd.ExcelWriter(output_file) data_frame.to_excel(writer, sheet_name='jan_13_output', index=False) writer.save()
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python pandas_parsing_and_write_keep_dates.py sales_2013.xlsx\ output_files\pandas_output.xls
你可以打开输出文件 pandas_output.xls 查看一下结果。
现在你已经明白了如何处理一个 Excel 工作簿中的工作表,以及如何保留日期格式,那么接下来学习一下如何在工作表中筛选出特定的行。正如我们在第 2 章中做的那样,接下来将讨论如何按照以下方式筛选行:(a)行中的值满足特定条件;(b)行中的值属于某个集合;(c)行中的值匹配于特定的正则表达式。
3.2.2 筛选特定行
有些时候,你并不需要 Excel 文件中的所有行。例如,你可能只需要包含一个特定的词或数值的那些行,或者,你可能只需要那些与一个具体日期相关联的行。在这些情况下,可以使用 Python 筛选掉不需要的行,只保留需要的行。
你可能已经熟悉了如何在 Excel 文件中手动筛选行,但是本章重点在于提高你的能力,使你可以处理因体积太大而难以打开的 Excel 文件,以及手动处理过于浪费时间的多个 Excel 工作表。
01. 行中的值满足某个条件
基础 Python。首先,来看一下如何使用基础 Python 筛选出特定的行。在这个示例中,你想筛选出 Sale Amount 大于 $1400.00 的行。
为了筛选出满足这个条件的行,在文本编辑器中输入下列代码,然后将文件保存为 4excel_value_meets_condition.py:
1 #!/usr/bin/env python3 2 import sys 3 from datetime import date 4 from xlrd import open_workbook, xldate_as_tuple 5 from xlwt import Workbook 6 input_file = sys.argv[1] 7 output_file = sys.argv[2] 8 output_workbook = Workbook() 9 output_worksheet = output_workbook.add_sheet('jan_2013_output') 10 sale_amount_column_index = 3 11 with open_workbook(input_file) as workbook: 12 worksheet = workbook.sheet_by_name('january_2013') 13 data = [] 14 header = worksheet.row_values(0) 15 data.append(header) 16 for row_index in range(1,worksheet.nrows): 17 row_list = [] 18 sale_amount = worksheet.cell_value\ 19 (row_index, sale_amount_column_index) 20 if sale_amount > 1400.0: 21 for column_index in range(worksheet.ncols): 22 cell_value = worksheet.cell_value\ 23 (row_index,column_index) 24 cell_type = worksheet.cell_type\ 25 (row_index, column_index) 26 if cell_type == 3: 27 date_cell = xldate_as_tuple\ 28 (cell_value,workbook.datemode) 29 date_cell = date(*date_cell[0:3])\ 30 .strftime('%m/%d/%Y') 31 row_list.append(date_cell) 32 else: 33 row_list.append(cell_value) 34 if row_list: 35 data.append(row_list) 36 for list_index, output_list in enumerate(data): 37 for element_index, element in enumerate(output_list): 38 output_worksheet.write(list_index, element_index, element) 39 output_workbook.save(output_file)
第 13 行代码创建了一个空列表 data。我们将用输入文件中要写入输出文件中的那些行来填充这个列表。
第 14 行代码提取出标题行中的值。因为我们想保留标题行,而且检验这一行是否满足筛选条件没有意义,所以第 15 行代码将标题行直接追加到 data 中。
第 18 行代码创建了一个变量 sale_amount,用来保存行中的销售额。cell_value 函数使用第 10 行代码中定义的 sale_amount_column_index 中的值来定位 Sale Amount 列。因为我们想保留销售额大于 $1400.00 的那些行,所以要使用这个变量作为检验条件。
第 21 行代码创建了一个 for 循环,来处理 Sale Amount 大于 1400.0 的那些行。对于这些行,我们先提取出每个单元格的值,赋给变量 cell_value,再提取出每个单元格的类型,赋给变量 cell_type。然后,检验行中的每个值是否是日期类型。如果是日期类型,那么就将这个值格式化成日期数据。为了生成一个每个值都正确格式化的行,我们在第 17 行创建了一个空列表 row_list,然后用第 31 和 33 行代码将行中的日期类型数据和非日期类型数据都追加进 row_list。
我们为输入文件中的每一行都创建空列表 row_list,但是只使用值填充某些空列表(就是 Sale Amount 这列的值大于 1400.0 的那些行的空列表)。所以,对于输入文件中的每一行,第 34 行代码检验 row_list 是否为空,只将非空的 row_list 添加到 data 中。
最后,在第 36 和 37 行代码中,我们在 data 中的各个列表之间和列表中的各个值之间进行迭代,将这些值写入输出文件。将要保留的行追加到一个新列表 data 中的原因是,这样可以得到新的连续的行索引值。于是,当我们将这些行写入输出文件时,它们看上去就像是一个连续的整体,行与行之间不会出现缺口。否则,如果在主体 for 循环中处理各行的时候就将它们写入输出文件的话,那么 xlwt 的 write 函数就会使用输入文件中原来的行索引值将行写入输出文件,造成行与行之间存在缺口。在后面选择特定列的小节中,我们还会使用这种方法,以此来保证将各列作为一个连续整体写入输出文件,列与列之间不出现缺口。
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python 4excel_value_meets_condition.py sales_2013.xlsx output_files\4output.xls
你可以打开输出文件 4output.xls 查看一下结果。
pandas。你可以使用 pandas 筛选出符合某个条件的行,指定你想判断的列的名称,并在数据框名称后面的方括号中设定具体的判断条件。例如,在下面的脚本中,我们设定的判断条件就可以筛选出 Sale Amount 列大于 1400.00 的所有行。
如果你需要设定多个条件,那么可以将这些条件放在圆括号中,根据需要的逻辑顺序用“&”或“|”连接起来。在注释掉的两行代码中,展示了如何基于两个条件来筛选行。第一行代码使用“&”,表示两个条件必须都为真。第二行代码使用“|”,表示只要一个条件为真就可以。(在下面的示例代码中,并没有加了注释的语句,应该是作者删掉了。——译者注)
要使用 pandas 筛选出满足特定条件的行,在文本编辑器中输入下列代码,然后将文件保存为 pandas_value_meets_condition.py:
#!/usr/bin/env python3 import pandas as pd import sys input_file = sys.argv[1] output_file = sys.argv[2] data_frame = pd.read_excel(input_file, 'january_2013', index_col=None) data_frame_value_meets_condition = \ data_frame[data_frame['Sale Amount'].astype(float) > 1400.0] writer = pd.ExcelWriter(output_file) data_frame_value_meets_condition.to_excel(writer, sheet_name='jan_13_output',\ index=False) writer.save()
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python pandas_value_meets_condition.py sales_2013.xlsx\ output_files\pandas_output.xls
你可以打开输出文件 pandas_output.xls 查看一下结果。
02. 行中的值属于某个集合
基础 Python。要使用基础 Python 筛选出购买日期属于一个特定集合(例如:日期 01/24/2013 和 01/31/2013 的集合)的行,在文本编辑器中输入下列代码,并将文件保存为 5excel_value_in_set.py:
1 #!/usr/bin/env python3 2 import sys 3 from datetime import date 4 from xlrd import open_workbook, xldate_as_tuple 5 from xlwt import Workbook 6 input_file = sys.argv[1] 7 output_file = sys.argv[2] 8 output_workbook = Workbook() 9 output_worksheet = output_workbook.add_sheet('jan_2013_output') 10 important_dates = ['01/24/2013', '01/31/2013'] 11 purchase_date_column_index = 4 12 with open_workbook(input_file) as workbook: 13 worksheet = workbook.sheet_by_name('january_2013') 14 data = [] 15 header = worksheet.row_values(0) 16 data.append(header) 17 for row_index in range(1, worksheet.nrows): 18 purchase_datetime = xldate_as_tuple(worksheet.cell_value\ 19 (row_index, purchase_date_column_index)\ 20 ,workbook.datemode) 21 purchase_date = date(*purchase_datetime[0:3]).strftime('%m/%d/%Y') 22 row_list = [] 23 if purchase_date in important_dates: 24 for column_index in range(worksheet.ncols): 25 cell_value = worksheet.cell_value\ 26 (row_index,column_index) 27 cell_type = worksheet.cell_type(row_index, column_index) 28 if cell_type == 3: 29 date_cell = xldate_as_tuple\ 30 (cell_value,workbook.datemode) 31 date_cell = date(*date_cell[0:3])\ 32 .strftime('%m/%d/%Y') 33 row_list.append(date_cell) 34 else: 35 row_list.append(cell_value) 36 if row_list: 37 data.append(row_list) 38 for list_index, output_list in enumerate(data): 39 for element_index, element in enumerate(output_list): 40 output_worksheet.write(list_index, element_index, element) 41 output_workbook.save(output_file)
这个脚本与基于条件筛选行的脚本非常相似,区别在于第 10、21 和 23 行。第 10 行代码创建了一个列表 important_dates,包含了要使用的日期。第 21 行代码创建了一个变量 purchase_date,它等于 Purchase Date 列中格式化后的值,并用它来匹配 important_dates 中格式化的日期。第 23 行代码检验行中的日期是否是 important_dates 中的一个日期。如果是,那么就处理这一行,并将其写入输出文件。
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python 5excel_value_in_set.py sales_2013.xlsx output_files\5output.xls
你可以打开输出文件 5output.xls 查看一下结果。
pandas。在这个示例中,我们想筛选出购买日期为 01/24/2013 或 01/31/2013 的行。pandas 提供了 isin 函数,你可以使用它来检验一个特定值是否在一个列表中。
要使用 pandas 基于集合成员筛选行,在文本编辑器中输入下列代码,然后将文件保存为 pandas_value_in_set.py:
#!/usr/bin/env python3 import pandas as pd import sys input_file = sys.argv[1] output_file = sys.argv[2] data_frame = pd.read_excel(input_file, 'january_2013', index_col=None) important_dates = ['01/24/2013','01/31/2013'] data_frame_value_in_set = data_frame[data_frame['PurchaseDate']\ .isin(important_dates)] writer = pd.ExcelWriter(output_file) data_frame_value_in_set.to_excel(writer, sheet_name='jan_13_output', index=False) writer.save()
在命令行中运行这个脚本:
python pandas_value_in_set.py sales_2013.xlsx output_files\pandas_output.xls
你可以打开输出文件 pandas_output.xls 查看一下结果。
03. 行中的值匹配于特定模式
基础 Python。要使用基础 Python 筛选出客户姓名包含一个特定模式(例如:以大写字母 J 开头)的行,在文本编辑器中输入下列代码,然后将文件保存为 6excel_value_matches_pattern.py:
1 #!/usr/bin/env python3 2 import re 3 import sys 4 from datetime import date 5 from xlrd import open_workbook, xldate_as_tuple 6 from xlwt import Workbook 7 input_file = sys.argv[1] 8 output_file = sys.argv[2] 9 output_workbook = Workbook() 10 output_worksheet = output_workbook.add_sheet('jan_2013_output') 11 pattern = re.compile(r'(?P<my_pattern>^J.*)') 12 customer_name_column_index = 1 13 with open_workbook(input_file) as workbook: 14 worksheet = workbook.sheet_by_name('january_2013') 15 data = [] 16 header = worksheet.row_values(0) 17 data.append(header) 18 for row_index in range(1, worksheet.nrows): 19 row_list = [] 20 if pattern.search(worksheet.cell_value\ 21 (row_index, customer_name_column_index)): 22 for column_index in range(worksheet.ncols): 23 cell_value = worksheet.cell_value\ 24 (row_index,column_index) 25 cell_type = worksheet.cell_type(row_index, column_index) 26 if cell_type == 3: 27 date_cell = xldate_as_tuple\ 28 (cell_value,workbook.datemode) 29 date_cell = date(*date_cell[0:3])\ 30 .strftime('%m/%d/%Y') 31 row_list.append(date_cell) 32 else: 33 row_list.append(cell_value) 34 if row_list: 35 data.append(row_list) 36 for list_index, output_list in enumerate(data): 37 for element_index, element in enumerate(output_list): 38 output_worksheet.write(list_index, element_index, element) 39 output_workbook.save(output_file)
第 2 行代码导入 re 模块,以使我们可以使用模块中的函数和方法。
第 11 行代码使用 re 模块的 compile 函数创建了一个正则表达式 pattern。如果你能看懂,那么这个函数中的内容就很好解释。r 表示单引号之间的模式是一个原始字符串。元字符 ?P<my_pattern> 捕获了名为 <my_pattern> 的组中匹配了的子字符串,以便在需要时将它们打印到屏幕上或写入文件。我们要搜索的实际模式是 '^J.*'。插入符号(^)是一个特殊符号,表示“在字符串开头搜索模式”。所以,字符串需要以大写字母 J 开头。句点 . 可以匹配任何字符,除了换行符。所以除换行符之外的任何字符都可以跟在 J 后面。最后,* 表示重复前面的字符 0 次或更多次。.* 组合在一起用来表示除换行符之外的任意字符可以在 J 后面出现任意次。
第 20 行代码使用 re 模块中的 search 函数在 Customer Name 列中搜索模式,并检测是否能找到一个匹配。如果找到了一个匹配,就将这一行中的每个值添加到 row_list 中。第 31 行代码将日期值添加到 row_list 中,第 33 行代码将非日期值添加到 row_list 中。如果 row_list 不是空的,第 35 行代码将 row_list 中的每个列表值添加到 data。
最后,第 36 和 37 行代码中的两个 for 循环在 data 中的各个列表中迭代,将各行写入输出文件。
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python 6excel_value_matches_pattern.py sales_2013.xlsx output_files\6output.xls
你可以打开输出文件 6output.xls 查看一下结果。
pandas。在这个示例中,你想筛选出客户姓名以大写字母 J 开头的那些行。pandas 提供了若干字符串和正则表达式函数,包括 startswith、endswith、match 和 search 等,你可以使用这些函数在文本中识别子字符串和模式。
要使用 pandas 筛选出客户姓名以大写字母 J 开头的那些行,在文本编辑器中输入下列代码,然后将文件保存为 pandas_value_matches_pattern.py:
#!/usr/bin/env python3 import pandas as pd import sys input_file = sys.argv[1] output_file = sys.argv[2] data_frame = pd.read_excel(input_file, 'january_2013', index_col=None) data_frame_value_matches_pattern = data_frame[data_frame['Customer Name']\ .str.startswith("J")] writer = pd.ExcelWriter(output_file) data_frame_value_matches_pattern.to_excel(writer, sheet_name='jan_13_output',\ index=False) writer.save()
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python pandas_value_matches_pattern.py sales_2013.xlsx\ output_files\pandas_output.xls
你可以打开输出文件 pandas_output.xls 查看一下结果。
3.2.3 选取特定列
有些时候,你并不需要工作表中所有的列。在这种情况下,可以使用 Python 选取出你需要保留的列。
有两种通用方法可以在 Excel 文件中选取特定的列。下面的小节演示了这两种选取列的方法:
· 使用列索引值
· 使用列标题
· 列索引值
基础 Python。从工作表中选取特定列的一种方法是使用要保留的列的索引值。当你想保留的列的索引值非常容易识别,或者在处理多个输入文件过程中,各个输入文件中列的位置是一致(也就是不会发生改变)的时候,这种方法非常有效。
例如,假设我们想保留 Customer Name 和 Purchase Date 这两列。要使用基础 Python 选取这两列,在文本编辑器中输入下列代码,然后将文件保存为 7excel_column_by_index.py:
1 #!/usr/bin/env python3 2 import sys 3 from datetime import date 4 from xlrd import open_workbook, xldate_as_tuple 5 from xlwt import Workbook 6 input_file = sys.argv[1] 7 output_file = sys.argv[2] 8 output_workbook = Workbook() 9 output_worksheet = output_workbook.add_sheet('jan_2013_output') 10 my_columns = [1, 4] 11 with open_workbook(input_file) as workbook: 12 worksheet = workbook.sheet_by_name('january_2013') 13 data = [] 14 for row_index in range(worksheet.nrows): 15 row_list = [] 16 for column_index in my_columns: 17 cell_value = worksheet.cell_value(row_index,column_index) 18 cell_type = worksheet.cell_type(row_index, column_index) 19 if cell_type == 3: 20 date_cell = xldate_as_tuple\ 21 (cell_value,workbook.datemode) 22 date_cell = date(*date_cell[0:3]).strftime('%m/%d/%Y') 23 row_list.append(date_cell) 24 else: 25 row_list.append(cell_value) 26 data.append(row_list) 27 for list_index, output_list in enumerate(data): 28 for element_index, element in enumerate(output_list): 29 output_worksheet.write(list_index, element_index, element) 30 output_workbook.save(output_file)
第 10 行代码创建了一个列表变量 my_columns,包含整数 1 和 4。这两个整数分别代表 Customer Name 和 Purchase Date 列的索引值。
第 16 行代码创建了一个 for 循环,在 my_columns 中的两个列索引值之间迭代。在每次循环中,提取出列中单元格的值和类型,判断单元格中的值是否是日期类型,并对单元格进行相应处理,然后将值追加到 row_list 中。第 26 行代码将 row_list 中的值添加到 data 中。
最后,第 27 和 28 行代码中的两个 for 循环在 data 中的列表之间迭代,将其中的值写入输出文件。
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python 7column_column_by_index.py sales_2013.xlsx output_files\7output.xls
你可以打开输出文件 7output.xls 查看一下结果。
pandas。有很多方法可以使用 pandas 选取特定列。一种方法是设置数据框,在方括号中列出要保留的列的索引值或名称(字符串)。
另一种方法,也就是下面所展示的,是设置数据框和 iloc 函数。iloc 函数非常有用,因为它可以使你同时选择特定的行与特定的列。所以,如果使用 iloc 函数来选择列,那么就需要在列索引值前面加上一个冒号和一个逗号,表示你想为这些特定的列保留所有的行。否则,iloc 函数也会使用这些索引值去筛选行。
要使用 pandas 基于索引值去选取列,在文本编辑器中输入下列代码,然后将文件保存为 pandas_column_by_index.py:
#!/usr/bin/env python3 import pandas as pd import sys input_file = sys.argv[1] output_file = sys.argv[2] data_frame = pd.read_excel(input_file, 'january_2013', index_col=None) data_frame_column_by_index = data_frame.iloc[:, [1, 4]] writer = pd.ExcelWriter(output_file) data_frame_column_by_index.to_excel(writer, sheet_name='jan_13_output',\ index=False) writer.save()
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python pandas_column_by_index.py sales_2013.xlsx output_files\pandas_output.xls
你可以打开输出文件 pandas_output.xls 查看一下结果。
· 列标题
第二种在工作表中选取一组列的方法是使用列标题。当你想保留的列的标题非常容易识别,或者在处理多个输入文件过程中,各个输入文件中列的位置会发生改变,但标题不变的时候,这种方法非常有效。
基础 Python。要使用基础 Python 选取 Customer ID 和 Purchase Date 列,在文本编辑器中输入下列代码,然后将文件保存为 8excel_column_by_name.py:
1 #!/usr/bin/env python3 2 import sys 3 from datetime import date 4 from xlrd import open_workbook, xldate_as_tuple 5 from xlwt import Workbook 6 input_file = sys.argv[1] 7 output_file = sys.argv[2] 8 output_workbook = Workbook() 9 output_worksheet = output_workbook.add_sheet('jan_2013_output') 10 my_columns = ['Customer ID', 'Purchase Date'] 11 with open_workbook(input_file) as workbook: 12 worksheet = workbook.sheet_by_name('january_2013') 13 data = [my_columns] 14 header_list = worksheet.row_values(0) 15 header_index_list = [] 16 for header_index in range(len(header_list)): 17 if header_list[header_index] in my_columns: 18 header_index_list.append(header_index) 19 for row_index in range(1,worksheet.nrows): 20 row_list = [] 21 for column_index in header_index_list: 22 cell_value = worksheet.cell_value(row_index,column_index) 23 cell_type = worksheet.cell_type(row_index, column_index) 24 if cell_type == 3: 25 date_cell = xldate_as_tuple\ 26 (cell_value,workbook.datemode) 27 date_cell = date(*date_cell[0:3]).strftime('%m/%d/%Y') 28 row_list.append(date_cell) 29 else: 30 row_list.append(cell_value) 31 data.append(row_list) 32 for list_index, output_list in enumerate(data): 33 for element_index, element in enumerate(output_list): 34 output_worksheet.write(list_index, element_index, element) 35 output_workbook.save(output_file)
第 10 行代码创建了一个列表变量 my_columns,包含要保留的两列的名称。因为这是要写入输出文件的列标题,所以在第 13 行代码中,直接将其加入输出列表 data。
第 16 行代码创建了一个 for 循环,在 header_list 中的列标题索引值之间迭代。第 17 行代码使用列表索引来检验每个列标题是否在列表 my_columns 中。如果是,就使用第 18 行代码将这个列标题的索引值追加到 header_index_list 中。后面将在第 21 行代码中使用这些索引值,仅处理那些要写入输出文件的列。
第 21 行代码创建了一个 for 循环,在 header_index_list 中的列索引值之间迭代。通过使用 header_index_list,只处理在 my_columns 中列出的那些列。
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python 8excel_column_by_name.py sales_2013.xlsx output_files\8output.xls
你可以打开输出文件 8output.xls 查看一下结果。
pandas。要使用 pandas 基于列标题选取特定列,一种方式是在数据框名称后面的方括号中将列名以字符串方式列出。另外一种方式是使用 loc 函数。如果使用 loc 函数,那么需要在列标题列表前面加上一个冒号和一个逗号,表示你想为这些特定的列保留所有行。
要使用 pandas 基于列标题选取列,在文本编辑器中输入下列代码,然后将文件保存为 pandas_column_by_name.py:
#!/usr/bin/env python3 import pandas as pd import sys input_file = sys.argv[1] output_file = sys.argv[2] data_frame = pd.read_excel(input_file, 'january_2013', index_col=None) data_frame_column_by_name = data_frame.loc[:, ['Customer ID', 'Purchase Date']] writer = pd.ExcelWriter(output_file) data_frame_column_by_name.to_excel(writer, sheet_name='jan_13_output',\ index=False) writer.save()
要运行这个脚本,在命令行中输入以下命令,然后按回车键:
python pandas_column_by_name.py sales_2013.xlsx output_files\pandas_output.xls
你可以打开输出文件 pandas_output.xls 查看一下结果。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论