อ่านไฟล์ 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

คำตอบ:


71

นี่เป็นแนวทางหนึ่ง:

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

91

คำตอบค่อนข้างช้า แต่ด้วยแพนด้าคุณสามารถรับคอลัมน์ของไฟล์ 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
nishant

9
ไม่จำเป็นต้องนำเข้า xlrd เพียงตรวจสอบให้แน่ใจว่าได้ติดตั้ง xlrd แล้วแพนด้าจะนำเข้าและใช้งานได้
Vaibhav Vishal

12

ดังนั้นส่วนสำคัญคือการจับส่วนหัว ( 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

7

ด้วยการใช้แพนด้าเราสามารถอ่าน excel ได้อย่างง่ายดาย

import pandas as pd 
from pandas import ExcelWriter
from pandas import ExcelFile 

DataF=pd.read_excel("Test.xlsx",sheet_name='Sheet1')

print("Column headings:")
print(DataF.columns)

ทดสอบได้ที่: https://repl.it อ้างอิง: https://pythonspot.com/read-excel-with-pandas/


2
ทำไมคุณถึงนำเข้าxlrd?
Anaphory

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

และเพราะฉัน Noob หลามอุปกรณ์ประกอบฉากที่จะ: คำตอบนี้ , คำตอบนี้ , คำถามนี้ , คำถามนี้ และคำตอบนี้


ฉันคิดว่าfirstRow[x].valueควรจะเป็นheaderRow[x].value
TSeymour

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.