Đọc tệp Excel bằng Python


88

Tôi có một tệp 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

Tôi muốn lưu một chuỗi trong biểu mẫu Arm_id,DSPCode,Pincode. Định dạng này có thể định cấu hình, tức là nó có thể thay đổi thành DSPCode,Arm_id,Pincode. Tôi lưu nó trong một danh sách như:

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

Làm cách nào để đọc nội dung của một cột cụ thể với tên được cung cấp, với điều kiện FORMATlà có thể định cấu hình?

Đây là những gì tôi đã thử. Hiện tại tôi có thể đọc tất cả nội dung trong tệp

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 ra của tôi là

[[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']]

Sau đó, tôi lặp đi lặp lại values[0]để cố gắng tìm ra FORMATnội dung trong values[0]đó và sau đó lấy chỉ mục của Arm_id, DSPname and Pincodetrong values[0]và sau đó từ vòng lặp tiếp theo, tôi biết chỉ số của tất cả các FORMATyếu tố, từ đó biết mình cần lấy giá trị nào.

Nhưng đây là một giải pháp kém.

Làm cách nào để lấy giá trị của một cột cụ thể có tên trong tệp excel?


Bạn nên sử dụng một dict()hoặc tạo lớp dữ liệu của riêng bạn.
tamasgal

Như thế nào? bạn có thể vui lòng cung cấp một mã mẫu?
PythonE say mê

Câu trả lời:


70

Đây là một cách tiếp cận:

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

Bạn không cần phải sử dụng một lớp tùy chỉnh, bạn có thể chỉ cần lấy một dict(). Tuy nhiên, nếu bạn sử dụng một lớp, bạn có thể truy cập tất cả các giá trị thông qua ký hiệu dấu chấm, như bạn thấy ở trên.

Đây là đầu ra của tập lệnh ở trên:

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

Một câu trả lời hơi muộn, nhưng với gấu trúc, có thể lấy trực tiếp một cột của tệp 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]

Đảm bảo rằng bạn đã cài đặt xlrd và pandas:

pip install pandas xlrd

2
Thêm import xlrdở trên cùng để làm cho công việc này. read_excelyêu cầu xlrd. Nếu nhận được ImportError: No module named 'xlrd', sau đó làmpip install xlrd
nishant

9
Nhập xlrd là không cần thiết, chỉ cần đảm bảo xlrd được cài đặt, gấu trúc sẽ nhập và sử dụng nó.
Vaibhav Vishal

12

Vì vậy, các phần quan trọng là lấy tiêu đề ( col_names = s.row(0)) và khi lặp qua các hàng, bỏ qua hàng đầu tiên không cần thiết for row in range(1, s.nrows)- được thực hiện bằng cách sử dụng phạm vi từ 1 trở đi (không phải số 0 ngầm định). Sau đó, bạn sử dụng zip để bước qua các hàng giữ 'tên' làm tiêu đề của cột.

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

Đây là mã để đọc tệp excel và in tất cả các ô có trong cột 1 (ngoại trừ ô đầu tiên tức là tiêu đề):

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

Cách tiếp cận tôi đã thực hiện đọc thông tin tiêu đề từ hàng đầu tiên để xác định chỉ mục của các cột quan tâm.

Bạn đã đề cập trong câu hỏi rằng bạn cũng muốn các giá trị xuất ra một chuỗi. Tôi tạo động một chuỗi định dạng cho đầu ra từ danh sách cột ĐỊNH DẠNG. Các hàng được nối vào chuỗi giá trị được phân tách bằng một ký tự dòng mới.

Thứ tự cột đầu ra được xác định bởi thứ tự của tên cột trong danh sách ĐỊNH DẠNG.

Trong mã của tôi bên dưới, trường hợp tên cột trong danh sách ĐỊNH DẠNG là quan trọng. Trong câu hỏi ở trên, bạn đã có 'Pincode' trong danh sách ĐỊNH DẠNG, nhưng lại có 'PinCode' trong excel của bạn. Điều này sẽ không hoạt động bên dưới, nó sẽ cần phải là 'Mã pin'.

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

Đối với đầu vào mẫu mà bạn đã cung cấp ở trên, đầu ra mã này:

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

Và bởi vì tôi là một Noob python, đạo cụ thể để: câu trả lời này , câu trả lời này , câu hỏi này , câu hỏi này và câu trả lời này .


Tôi nghĩ firstRow[x].valuelà phảiheaderRow[x].value
TSeymour

0

Mặc dù tôi hầu như luôn chỉ sử dụng gấu trúc cho việc này, nhưng công cụ nhỏ hiện tại của tôi đang được đóng gói thành tệp thực thi và bao gồm cả gấu trúc là quá mức cần thiết. Vì vậy, tôi đã tạo một phiên bản giải pháp của poida dẫn đến một danh sách các bộ giá trị được đặt tên. Mã của anh ấy với thay đổi này sẽ trông như thế này:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.