Прочитать файл Excel на Python


88

У меня есть файл Excel

Arm_id      DSPName        DSPCode          HubCode          PinCode    PPTL
1            JaVAS            01              AGR             282001    1,2
2            JaVAS            01              AGR             282002    3,4
3            JaVAS            01              AGR             282003    5,6

Я хочу сохранить строку в форме Arm_id,DSPCode,Pincode. Этот формат можно настроить, т. Е. Он может измениться на DSPCode,Arm_id,Pincode. Я сохраняю это в списке вроде:

FORMAT = ['Arm_id', 'DSPName', 'Pincode']

Как мне прочитать содержимое определенного столбца с указанным именем, если его FORMATможно настроить?

Это то, что я пробовал. В настоящее время я могу прочитать все содержимое файла

from xlrd import open_workbook
wb = open_workbook('sample.xls')
for s in wb.sheets():
    #print 'Sheet:',s.name
    values = []
    for row in range(s.nrows):
        col_value = []
        for col in range(s.ncols):
            value  = (s.cell(row,col).value)
            try : value = str(int(value))
            except : pass
            col_value.append(value)
        values.append(col_value)
print values

Мой результат

[[u'Arm_id', u'DSPName', u'DSPCode', u'HubCode', u'PinCode', u'PPTL'], ['1', u'JaVAS', '1', u'AGR', '282001', u'1,2'], ['2', u'JaVAS', '1', u'AGR', '282002', u'3,4'], ['3', u'JaVAS', '1', u'AGR', '282003', u'5,6']]

Затем я values[0]пытаюсь найти FORMATсодержимое, values[0]а затем получить индекс Arm_id, DSPname and Pincodeв values[0]цикле, а затем в следующем цикле я знаю индекс всех FORMATфакторов, тем самым узнавая, какое значение мне нужно получить.

Но это такое плохое решение.

Как мне получить значения определенного столбца с именем в файле Excel?


Вы должны либо использовать, dict()либо создать свой собственный класс данных.
tamasgal

Например как? не могли бы вы предоставить образец кода?
PythonEnthusiast

Ответы:


70

Это один из подходов:

from xlrd import open_workbook

class Arm(object):
    def __init__(self, id, dsp_name, dsp_code, hub_code, pin_code, pptl):
        self.id = id
        self.dsp_name = dsp_name
        self.dsp_code = dsp_code
        self.hub_code = hub_code
        self.pin_code = pin_code
        self.pptl = pptl

    def __str__(self):
        return("Arm object:\n"
               "  Arm_id = {0}\n"
               "  DSPName = {1}\n"
               "  DSPCode = {2}\n"
               "  HubCode = {3}\n"
               "  PinCode = {4} \n"
               "  PPTL = {5}"
               .format(self.id, self.dsp_name, self.dsp_code,
                       self.hub_code, self.pin_code, self.pptl))

wb = open_workbook('sample.xls')
for sheet in wb.sheets():
    number_of_rows = sheet.nrows
    number_of_columns = sheet.ncols

    items = []

    rows = []
    for row in range(1, number_of_rows):
        values = []
        for col in range(number_of_columns):
            value  = (sheet.cell(row,col).value)
            try:
                value = str(int(value))
            except ValueError:
                pass
            finally:
                values.append(value)
        item = Arm(*values)
        items.append(item)

for item in items:
    print item
    print("Accessing one single value (eg. DSPName): {0}".format(item.dsp_name))
    print

Вам не обязательно использовать собственный класс, вы можете просто взять dict(). Однако, если вы используете класс, вы можете получить доступ ко всем значениям через точечную нотацию, как вы видите выше.

Вот результат выполнения сценария выше:

Arm object:
  Arm_id = 1
  DSPName = JaVAS
  DSPCode = 1
  HubCode = AGR
  PinCode = 282001 
  PPTL = 1
Accessing one single value (eg. DSPName): JaVAS

Arm object:
  Arm_id = 2
  DSPName = JaVAS
  DSPCode = 1
  HubCode = AGR
  PinCode = 282002 
  PPTL = 3
Accessing one single value (eg. DSPName): JaVAS

Arm object:
  Arm_id = 3
  DSPName = JaVAS
  DSPCode = 1
  HubCode = AGR
  PinCode = 282003 
  PPTL = 5
Accessing one single value (eg. DSPName): JaVAS

90

Несколько поздний ответ, но с помощью pandas можно напрямую получить столбец файла excel:

import pandas

df = pandas.read_excel('sample.xls')
#print the column names
print df.columns
#get the values for a given column
values = df['Arm_id'].values
#get a data frame with selected columns
FORMAT = ['Arm_id', 'DSPName', 'Pincode']
df_selected = df[FORMAT]

Убедитесь, что вы установили xlrd и pandas:

pip install pandas xlrd

2
Добавьте import xlrdвверху, чтобы заставить эту работу работать. read_excelтребует xlrd. Если ImportError: No module named 'xlrd'pip install xlrd
получится

9
импорт xlrd не требуется, просто убедитесь, что xlrd установлен, pandas будет импортировать и использовать его.
Вайбхав Вишал

12

Таким образом, ключевые части заключаются в том, чтобы захватить header ( col_names = s.row(0)) и при итерации по строкам пропустить первую строку, которая не нужна for row in range(1, s.nrows)- это делается с использованием диапазона от 1 и далее (а не неявного 0). Затем вы используете zip для перехода по строкам, содержащим «имя» в качестве заголовка столбца.

from xlrd import open_workbook

wb = open_workbook('Book2.xls')
values = []
for s in wb.sheets():
    #print 'Sheet:',s.name
    for row in range(1, s.nrows):
        col_names = s.row(0)
        col_value = []
        for name, col in zip(col_names, range(s.ncols)):
            value  = (s.cell(row,col).value)
            try : value = str(int(value))
            except : pass
            col_value.append((name.value, value))
        values.append(col_value)
print values


2

Вот код для чтения файла Excel и печати всех ячеек, присутствующих в столбце 1 (кроме первой ячейки, т.е. заголовка):

import xlrd

file_location="C:\pythonprog\xxx.xlsv"
workbook=xlrd.open_workbook(file_location)
sheet=workbook.sheet_by_index(0)
print(sheet.cell_value(0,0))

for row in range(1,sheet.nrows):
     print(sheet.cell_value(row,0))

1

Подход, который я использовал, считывает информацию заголовка из первой строки для определения индексов интересующих столбцов.

Вы упомянули в вопросе, что также хотите, чтобы значения выводились в строку. Я динамически создаю строку формата для вывода из списка столбцов FORMAT. Строки добавляются к строке значений, разделенных символом новой строки.

Порядок выходных столбцов определяется порядком имен столбцов в списке FORMAT.

В моем коде ниже важен регистр имени столбца в списке FORMAT. В приведенном выше вопросе у вас есть «Pincode» в вашем списке FORMAT, но «PinCode» в вашем Excel. Ниже это не сработает, это должен быть «PinCode».

from xlrd import open_workbook
wb = open_workbook('sample.xls')

FORMAT = ['Arm_id', 'DSPName', 'PinCode']
values = ""

for s in wb.sheets():
    headerRow = s.row(0)
    columnIndex = [x for y in FORMAT for x in range(len(headerRow)) if y == firstRow[x].value]
    formatString = ("%s,"*len(columnIndex))[0:-1] + "\n"

    for row in range(1,s.nrows):
        currentRow = s.row(row)
        currentRowValues = [currentRow[x].value for x in columnIndex]
        values += formatString % tuple(currentRowValues)

print values

Для примера ввода, который вы дали выше, этот код выводит:

>>> 1.0,JaVAS,282001.0
2.0,JaVAS,282002.0
3.0,JaVAS,282003.0

И поскольку я питон-нуб, мне нужно: этот ответ , этот ответ , этот вопрос , этот вопрос и этот ответ .


Думаю firstRow[x].value, должно бытьheaderRow[x].value
Цеймур

0

Хотя я почти всегда использую для этого только панды, мой текущий маленький инструмент упакован в исполняемый файл, и включение панд является излишним. Итак, я создал версию решения poida , которая привела к списку именованных кортежей. Его код с этим изменением будет выглядеть так:

from xlrd import open_workbook
from collections import namedtuple
from pprint import pprint

wb = open_workbook('sample.xls')

FORMAT = ['Arm_id', 'DSPName', 'PinCode']
OneRow = namedtuple('OneRow', ' '.join(FORMAT))
all_rows = []

for s in wb.sheets():
    headerRow = s.row(0)
    columnIndex = [x for y in FORMAT for x in range(len(headerRow)) if y == headerRow[x].value]

    for row in range(1,s.nrows):
        currentRow = s.row(row)
        currentRowValues = [currentRow[x].value for x in columnIndex]
        all_rows.append(OneRow(*currentRowValues))

pprint(all_rows)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.