关于Excel数据处理,很多同学可能用过Pyhton的pandas模块,可以方便的读取和转换Excel数据。但在现实中,Excel表格的结构可能比较杂乱,数据会分散在不同的工作表中,表格中的分布非常杂乱。这种情况下,直接使用pandas会很困难。这篇文章冲冲给大家介绍一下如何使用pandas和openpyxl来读取此类数据。问题来自pandasread_excel函数,它可以很好地读取Excel工作表。但是如果数据不是从头开始的,不是从A1单元格开始的连续表格,结果就不会很好。比如下面的sales表使用read_excel读取:读取结果如下:结果中title的表头变成了Unnamed,并且会增加很多positions的NaN列,列的值withemptyfields也会被转换为NaN,这显然不是我们所期望的。header和usecols参数对于这种非标准格式的表格,我们可以通过read_excel()的header和usecols参数来控制读取的选中列。importpandasaspfrompathlibimportPathsrc_file='sales.xlsx'的结果DataFrame包含我们期望的数据。header和usecols参数在代码中用来设置用来显示标题的列和要读取的字段:header参数是一个整数,从0开始索引,也就是选中的行,比如1表示第二个Excel中的行。usecols参数设置选中的Excel列范围(A-...),例如B:F表示读取B列到F列。在某些情况下,可能希望将列定义为数字列表。例如,可以定义整数列:df=pd.read_excel(src_file,header=1,usecols=[1,2,3,4,5])对于大型数据集(例如,每3列或仅evencolumns)遵循特定的数字模式,则此参数方法可能很有用。usecols也可以设置为从列名列表中读取。比如上面的例子也可以这样写:df=pd.read_excel(src_file,header=1,usecols=['item_type','orderid','orderdate','state','priority'])columnorder支持自由选择,这种命名columnlist的方式其实很好用。usecols支持一个回调函数column_check,通过它可以对数据进行处理。这是一个简单的例子:defcolumn_check(x):if'unnamed'inx.lower():returnFalseif'priority'inx.lower():returnFalseif'order'inx.lower():returnTruereturnTruedf=pd.read_excel(src_file,header=1,usecols=column_check)column_check按名称解析每一列,每一列可以通过定义True或False来选择是否读取。usecols也可以使用lambda表达式。需要显示的字段列表在下面的示例中定义。为了比较,通过将名称转换为小写来规范化。cols_to_use=['item_type','orderid','orderdate','state','priority']df=pd.read_excel(src_file,header=1,usecols=lambdax:x.lower()incols_to_use)回调函数提供很大的灵活性来处理真正混乱的Excel文件。read_exce函数的更多参数可以查看官方文档。下面是一个汇总表:结合openpyxl在某些情况下,数据在Excel中甚至会变得更加复杂。在下面的示例中,我们有一个要读取的ship_cost表。如果您必须使用这样的文件,那么仅使用pandas函数和选项也很难做到。这种情况下可以直接使用openpyxl来解析文件,将数据转换成pandasDataFrame。例如读取下例的数据:fromopenpyxlimportload_workbookimportpandasaspfrompathlibimportPathsrc_file='sales1.xlsx'加载整个工作簿:cc=load_workbook(filename=src_file)查看所有工作表:cc.sheetnames['sales','shipping_rates']即可访问特定工作表:sheet=cc['shipping_rates']查看所有命名工作表的列表:sheet.tables.keys()dict_keys(['ship_cost'])键对应于在Excel中分配给工作表的名称。这样就可以设置要读取的Excel范围:lookup_table=sheet.tables['ship_cost']lookup_table.ref'C8:E16',从而得到要加载的数据范围。最后将其转换为pandasDataFrame。遍历每一行并转换为DataFrame:data=sheet[lookup_table.ref]rows_list=[]forrowindata:cols=[]forcolinrow:cols.append(col.value)rows_list.append(cols)df=pd.DataFrame(data=rows_list[1:],index=None,columns=rows_list[0])结果数据框:总结理想情况下,所使用的数据将采用简单且一致的格式。在本文中,我们介绍了如何轻松删除Pandas参数下的行和列,使其更合理。尤其是结合openpyxl,可以让我们更灵活的读取Excel数据,可以处理更复杂的表格数据。
