使用Pandas读取结构不良的Excel文件-实用业务Python

2020-10-21 09:01:49

使用PANDA很容易读取Excel文件并将数据转换为DataFrame。不幸的是,现实世界中的Excel文件结构通常很差。在数据分散在工作表中的情况下,您可能需要自定义读取数据的方式。本文将讨论如何使用Pandas和openpyxl读取这些类型的Excel文件,并干净利落地将数据转换成适合进一步分析的DataFrame。

PANDA READ_EXCEL函数在读取Excel工作表方面做得非常好。但是,如果数据不是从单元格A1开始的连续表格,结果可能与您预期的不同。

这些结果包括许多未命名的列、一行中的标题标签以及几个我们不需要的额外列。

此数据集的最简单解决方案是使用头和使用参数read_excel()。尤其是usecols参数,对于控制您想要包含的列可能非常有用。

如果您想跟随这些示例操作,可以在GitHub上找到该文件。

从pathlib导入路径src_file=path将熊猫作为pd导入。CWD()/';Shipping_tables.xlsx';df=pd。READ_EXCEL(src_file,Header=1,usecols=';B:F';)。

逻辑相对简单明了。Usecol可以接受Excel范围(如B:F),并且只读入这些列。Header参数需要定义标题列的单个整数。该值是0索引的,因此我们传入1,即使这是Excel中的第2行。

在某些情况下,我们可能希望将列定义为数字列表。在此示例中,我们可以定义四个整数的列表:

如果您希望对大型数据集遵循某种数字模式(即每3列或仅偶数编号的2列),则此方法可能很有用。

熊猫usecol还可以使用列名列表。此代码将创建一个等效的DataFrame:

如果列顺序改变了,但是您知道名称不会改变,那么使用命名列的列表会很有帮助。

最后,usecols可以接受可调用的函数。下面是一个简单的长格式示例,它不包括未命名列和优先级列。

#定义一个更复杂的函数:def column_check(X):if';unname';in x。LOWER():如果x中的优先级为False,则返回False。LOWER():如果x中的订单为';,则返回FALSE。LOWER():返回True返回True DF=PD。READ_EXCEL(src_file,Header=1,usecols=column_check)。

要记住的关键概念是,该函数将按名称解析每列,并为每列指定一个True或False。那些评估为True的列将不包括在内。

使用Callable的另一种方法是包含一个lambda表达式。下面是一个示例,其中我们只想包含已定义的列列表。我们通过将名称转换为小写来标准化名称,以便进行比较。

COLS_TO_USE=[';ITEM_TYPE';,';订单ID';,';订单日期';,';状态';,';优先级';]DF=PD。Read_excel(src_file,Header=1,usecols=lambda x:x.。COLS_TO_USE中的LOWER()

可调用的函数给了我们很大的灵活性来处理Excel文件的现实世界中的杂乱无章。

在某些情况下,数据在Excel中可能会更加模糊。在本例中,我们有一个要读取的名为SHIP_COST的表。如果您必须使用这样的文件,阅读我们到目前为止已经讨论过的熊猫选项可能会很有挑战性。

在这种情况下,我们可以直接使用openpyxl解析文件并将数据转换为熊猫DataFrame。数据在Excel表格中这一事实可以使这一过程变得更容易一些。

下面介绍如何使用openpyxl(一旦安装)读取Excel文件:

从openpyxl导入load_workbook将熊猫作为pd从pathlib导入路径src_file=src_file=path导入。Cwd()/';Shipping_tables.xlsx';wb=load_workbook(filename=src_file)。

此键与我们在Excel中分配给表的名称相对应。现在,我们访问该表以获取等效的Excel范围:

这招奏效了。我们现在知道了要加载的数据范围。最后一步是将该范围转换为熊猫数据帧。下面是一个简短的代码片段,用于循环每行并将其转换为一个完整的DataFrame:

#访问表范围DATA=SHEET[LOOKUP_TABLE]中的数据。Ref]ROWS_LIST=[]#循环每行并获取数据中行的单元格中的值:#获取每行中所有列的列表COLLES=[]FOR COLOR in ROW:COLS。追加(Col.。值)ROWS_LIST。APPEND(COLS)#从ROWS_LIST创建一个PANDA数据帧。#第一行是列名df=pd。DataFrame(DATA=ROWS_LIST[1:],INDEX=NONE,COLUMNS=ROWS_LIST[0])