【问题标题】:How to read Excel data by column name in python using xlrd如何使用 xlrd 在 python 中按列名读取 Excel 数据
【发布时间】:2019-04-17 21:54:19
【问题描述】:

我正在尝试读取大型 excel 文件的数据(几乎 100000 行)。 我在 python 中使用“xlrd 模块”从 excel 中获取数据。 我想按列名(Cascade,Schedule Name,Market)而不是列号(0,1,2)获取数据。 因为我的 excel 列不固定。 我知道如何在固定列的情况下获取数据。

这是我从 excel 中获取固定列数据的代码

import xlrd

file_location =r"C:\Users\Desktop\Vision.xlsx"
workbook=xlrd.open_workbook(file_location)
sheet= workbook.sheet_by_index(0)
print(sheet.ncols,sheet.nrows,sheet.name,sheet.number)

for i in range(sheet.nrows):
   flag = 0
   for j in range(sheet.ncols):
      value=sheet.cell(i,j).value

如果有人对此有任何解决方案,请告诉我

谢谢

【问题讨论】:

  • Edit你的问题并举一个例子“按列名而不是列号”
  • 我对我的问题进行了修改。
  • 你能告诉我怎么做吗?

标签: python excel python-3.x xlrd


【解决方案1】:

您可以使用熊猫。下面是用于识别 Excel 工作表中的列和行的示例代码。

import pandas as pd

file_location =r"Your_Excel_Path"

# Read out first sheet of excel file and return as pandas dataframe
df = pd.read_excel(file_location)


total_rows=len(df.axes[0])
total_cols=len(df.axes[1])

# Print total number of rows in an excel sheet
print("Number of Rows: "+str(total_rows))

# Print total number of columns in an excel sheet
print("Number of Columns: "+str(total_cols))

# Print column names in an excel sheet
print(df.columns.ravel())

现在,一旦您有了列数据,就可以将其转换为值列表。

【讨论】:

  • 正如 op 评论 @Xukrao 的回答也使用 pandas,op 不知道如何使用 pandas。
【解决方案2】:

评论:当
fieldnames = ['Cascade', 'Market', 'Schedule', 'Name]
Sheet(['Cascade', 'Schedule', 'Name', 'Market']) 的标头相等时仍然无法正常工作。

col_idx 中保持fieldnames 的顺序不是我最初的目标。


问题:我想按列名获取数据

以下OOP 解决方案将起作用:

class OrderedByName():
    """
    Privides a generator method, to iterate in Column Name ordered sequence
    Provides subscription, to get columns index by name. using class[name]
    """
    def __init__(self, sheet, fieldnames, row=0):
        """
        Create a OrderedDict {name:index} from 'fieldnames'
        :param sheet: The Worksheet to use
        :param fieldnames: Ordered List of Column Names
        :param row: Default Row Index for the Header Row
        """
        from collections import OrderedDict
        self.columns = OrderedDict().fromkeys(fieldnames, None)
        for n in range(sheet.ncols):
            self.columns[sheet.cell(row, n).value] = n

    @property
    def ncols(self):
        """
        Generator, equal usage as range(xlrd.ncols), 
          to iterate columns in ordered sequence
        :return: yield Column index
        """
        for idx in self.columns.values():
            yield idx

    def __getitem__(self, item):
        """
        Make class object subscriptable
        :param item: Column Name
        :return: Columns index
        """
        return self.columns[item]

用法

# Worksheet Data
sheet([['Schedule', 'Cascade', 'Market'],
       ['SF05UB0', 'DO Macro Upgrade', 'Upper Cnetral Valley'],
       ['DE03HO0', 'DO Macro Upgrade', 'Toledo'],
       ['SF73XC4', 'DO Macro Upgrade', 'SF Bay']]
      )

# Instantiate with Ordered List of Column Names
# NOTE the different Order of Column Names
by_name = OrderedByName(sheet, ['Cascade', 'Market', 'Schedule'])

# Iterate all Rows and all Columns Ordered as instantiated
for row in range(sheet.nrows):
    for col in by_name.ncols:
        value = sheet.cell(row, col).value
        print("cell({}).value == {}".format((row,col), value))

输出

cell((0, 1)).value == Cascade
cell((0, 2)).value == Market
cell((0, 0)).value == Schedule
cell((1, 1)).value == DO Macro Upgrade
cell((1, 2)).value == Upper Cnetral Valley
cell((1, 0)).value == SF05UB0
cell((2, 1)).value == DO Macro Upgrade
cell((2, 2)).value == Toledo
cell((2, 0)).value == DE03HO0
cell((3, 1)).value == DO Macro Upgrade
cell((3, 2)).value == SF Bay
cell((3, 0)).value == SF73XC4

按名称获取一个列的索引

print("cell{}.value == {}".format((1, by_name['Schedule']),
                                    sheet.cell(1, by_name['Schedule']).value))
#>>> cell(1, 0).value == SF05UB0

用 Python 测试:3.5

【讨论】:

  • 感谢 stovfl 的回答,但您只打印列索引,但我想打印列名对应的所有数据。你能告诉我如何使用这些列索引来获取它的对应行数据
  • @George.S:来自您的问题:“我知道如何在固定列的情况下获取数据。”Edit你提出问题并显示一个未修复数据表以及你如何使用col_idx列表来做到这一点。
  • 其实“我知道如何在固定列的情况下获取数据。”但问题是,如果我更改了我的 excel 的列标题,那么在你的代码中。它以相同的顺序打印列索引。所以告诉我我的代码如何知道哪个标题位于哪个列中。我想我已经澄清了我的观点。
  • 感谢更新,但是当字段名['Cascade', 'Market', 'Schedule', 'Name] 和 Sheet(['Cascade', 'Schedule', '名称','市场'])是相等的。它没有显示列标题的确切位置。
【解决方案3】:

您的列名在电子表格的第一行,对吗?因此,读取第一行并构建从名称到列索引的映射。

column_pos = [ (sheet.cell(0, i).value, i) for i in range(sheet.ncols) ]
colidx = dict(column_pos)

或作为单行:

colidx = dict( (sheet.cell(0, i).value, i) for i in range(sheet.ncols) )

然后您可以使用索引来解释列名,例如:

print(sheet.cell(5, colidx["Schedule Name"]).value)

要获取一整列,您可以使用列表推导:

schedule = [ sheet.cell(i, colidx["Schedule Name"]).value for i in range(1, sheet.nrows) ]

如果您真的想要,您可以为处理解释的cell 函数创建一个包装器。但我认为这很简单。

【讨论】:

  • 感谢亚历克西斯的回答。我想获取“计划名称”的完整数据而不是单个值。你能告诉我怎么做吗?
  • 完成。 (我假设第 0 行包含列名,因此它不包含在列值中。)
【解决方案4】:

您也可以使用pandas,这是一个内置excel I/O capabilities的综合数据分析库。

import pandas as pd

file_location =r"C:\Users\esatnir\Desktop\Sprint Vision.xlsx"

# Read out first sheet of excel file and return as pandas dataframe
df = pd.read_excel(file_location)

# Reduce dataframe to target columns (by filtering on column names)
df = df[['Cascade', 'Schedule Name', 'Market']]

结果数据框df 的快速视图将显示在哪里:

In [1]: df
Out[1]:
   Cascade     Schedule Name                Market
0  SF05UB0  DO Macro Upgrade  Upper Central Valley
1  DE03HO0  DO Macro Upgrade                Toledo
2  SF73XC4  DO Macro Upgrade                SF Bay

【讨论】:

  • 感谢 Xukrao 的回答,但我不知道如何使用 pandas 对 excel 数据执行操作。所以我无法使用它。
猜你喜欢
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
  • 2020-12-27
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多