Lesen Sie die Excel-Datei in Python


83

Ich habe eine Excel-Datei

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

Ich möchte eine Zeichenfolge im Formular speichern Arm_id,DSPCode,Pincode. Dieses Format ist konfigurierbar, dh es kann sich ändern zu DSPCode,Arm_id,Pincode. Ich speichere es in einer Liste wie:

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

Wie lese ich den Inhalt einer bestimmten Spalte mit dem angegebenen Namen, sofern der FORMATkonfigurierbar ist?

Das habe ich versucht. Derzeit kann ich den gesamten Inhalt der Datei lesen

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

Meine Ausgabe ist

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

Dann mache ich eine Schleife, um values[0]herauszufinden, FORMATin welchem Inhalt ich mich befinde, und erhalte values[0]dann den Index von Arm_id, DSPname and Pincodein values[0]und in der nächsten Schleife kenne ich den Index aller FORMATFaktoren, um herauszufinden, welchen Wert ich erhalten muss.

Aber das ist so eine schlechte Lösung.

Wie erhalte ich die Werte einer bestimmten Spalte mit Namen in der Excel-Datei?


Sie sollten entweder eine verwenden dict()oder eine eigene Datenklasse erstellen.
Tamasgal

Wie wie? Können Sie bitte einen Beispielcode angeben?
PythonEnthusiast

Antworten:


69

Dies ist ein Ansatz:

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

Sie müssen keine benutzerdefinierte Klasse verwenden, sondern können einfach eine nehmen dict(). Wenn Sie jedoch eine Klasse verwenden, können Sie wie oben gezeigt über die Punktnotation auf alle Werte zugreifen.

Hier ist die Ausgabe des obigen Skripts:

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

86

Eine etwas späte Antwort, aber mit Pandas ist es möglich, direkt eine Spalte einer Excel-Datei zu erhalten:

import pandas
import xlrd
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]

2
Fügen Sie import xlrdoben hinzu, damit dies funktioniert. read_excelerfordert xlrd. Wenn immer ImportError: No module named 'xlrd', dann tunpip install xlrd
nishant

7
Der Import von xlrd ist nicht erforderlich. Stellen Sie nur sicher, dass xlrd installiert ist. Pandas importiert und verwendet es.
Vaibhav Vishal

11

Die wichtigsten Teile sind also, den Header ( col_names = s.row(0)) zu greifen und beim Durchlaufen der Zeilen die erste Zeile zu überspringen, die nicht benötigt wird for row in range(1, s.nrows)- unter Verwendung des Bereichs ab 1 (nicht der impliziten 0). Anschließend verwenden Sie zip, um durch die Zeilen zu gehen, in denen 'name' als Kopfzeile der Spalte steht.

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

Hier ist der Code zum Lesen einer Excel-Datei und zum Drucken aller in Spalte 1 vorhandenen Zellen (mit Ausnahme der ersten Zelle, dh der Kopfzeile):

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

Der Ansatz, den ich gewählt habe, liest die Header-Informationen aus der ersten Zeile, um die Indizes der interessierenden Spalten zu bestimmen.

Sie haben in der Frage erwähnt, dass die Werte auch in eine Zeichenfolge ausgegeben werden sollen. Ich erstelle dynamisch eine Formatzeichenfolge für die Ausgabe aus der FORMAT-Spaltenliste. Zeilen werden an die Wertezeichenfolge angehängt, die durch ein neues Zeilenzeichen getrennt ist.

Die Reihenfolge der Ausgabespalten wird durch die Reihenfolge der Spaltennamen in der FORMAT-Liste bestimmt.

In meinem Code unten ist der Fall des Spaltennamens in der FORMAT-Liste wichtig. In der obigen Frage haben Sie 'Pincode' in Ihrer FORMAT-Liste, aber 'PinCode' in Ihrem Excel. Dies würde unten nicht funktionieren, es müsste 'PinCode' sein.

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

Für die Beispieleingabe, die Sie oben angegeben haben, gibt dieser Code Folgendes aus:

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

Und weil ich ein Python-Noob bin, sind Requisiten: diese Antwort , diese Antwort , diese Frage , diese Frage und diese Antwort .


Ich denke, firstRow[x].valuesoll seinheaderRow[x].value
TSeymour

0

Obwohl ich fast immer nur Pandas dafür benutze, wird mein aktuelles kleines Tool in eine ausführbare Datei gepackt und das Einbeziehen von Pandas ist übertrieben. Also habe ich eine Version von poidas Lösung erstellt, die zu einer Liste benannter Tupel führte. Sein Code mit dieser Änderung würde folgendermaßen aussehen:

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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.