Lire le fichier Excel en Python


88

J'ai un fichier 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

Je souhaite enregistrer une chaîne dans le formulaire Arm_id,DSPCode,Pincode. Ce format est configurable, c'est-à-dire qu'il peut devenir DSPCode,Arm_id,Pincode. Je l'enregistre dans une liste comme:

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

Comment lire le contenu d'une colonne spécifique avec le nom fourni, étant donné que le FORMATest configurable?

C'est ce que j'ai essayé. Actuellement, je suis capable de lire tout le contenu du fichier

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

Ma sortie est

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

Ensuite, je fais une boucle values[0]pour essayer de trouver le FORMATcontenu values[0], puis j'obtiens l'index de Arm_id, DSPname and Pincodela values[0]boucle suivante, puis je connais l'index de tous les FORMATfacteurs, apprenant ainsi à savoir quelle valeur dois-je obtenir.

Mais c'est une si mauvaise solution.

Comment obtenir les valeurs d'une colonne spécifique avec un nom dans un fichier Excel?


Vous devez utiliser un dict()ou créer votre propre classe de données.
tamasgal

Comme quoi? pouvez-vous s'il vous plaît fournir un exemple de code?
PythonEnthusiast

Réponses:


70

C'est une approche:

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

Vous n'êtes pas obligé d'utiliser une classe personnalisée, vous pouvez simplement prendre un dict(). Si vous utilisez une classe cependant, vous pouvez accéder à toutes les valeurs via la notation par points, comme vous le voyez ci-dessus.

Voici la sortie du script ci-dessus:

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

Une réponse un peu tardive, mais avec les pandas, il est possible d'obtenir directement une colonne d'un fichier 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]

Assurez-vous d'avoir installé xlrd et pandas:

pip install pandas xlrd

2
Ajoutez import xlrden haut pour que cela fonctionne. read_excelexige xlrd. Si obtenir ImportError: No module named 'xlrd', alors faitespip install xlrd
nishant

9
l'importation de xlrd n'est pas nécessaire, assurez-vous simplement que xlrd est installé, les pandas l'importeront et l'utiliseront.
Vaibhav Vishal

12

Donc, les éléments clés sont de saisir l'en-tête ( col_names = s.row(0)) et lors de l'itération à travers les lignes, de sauter la première ligne qui n'est pas nécessaire for row in range(1, s.nrows)- en utilisant la plage à partir de 1 (pas le 0 implicite). Vous utilisez ensuite zip pour parcourir les lignes contenant «nom» comme en-tête de la colonne.

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

Voici le code pour lire un fichier excel et imprimer toutes les cellules présentes dans la colonne 1 (sauf la première cellule c'est à dire l'en-tête):

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

L'approche que j'ai adoptée lit les informations d'en-tête de la première ligne pour déterminer les index des colonnes d'intérêt.

Vous avez mentionné dans la question que vous souhaitez également que les valeurs soient sorties dans une chaîne. Je construis dynamiquement une chaîne de format pour la sortie de la liste de colonnes FORMAT. Les lignes sont ajoutées à la chaîne de valeurs séparées par un nouveau caractère de ligne.

L'ordre des colonnes de sortie est déterminé par l'ordre des noms de colonnes dans la liste FORMAT.

Dans mon code ci-dessous, le cas du nom de la colonne dans la liste FORMAT est important. Dans la question ci-dessus, vous avez «Pincode» dans votre liste FORMAT, mais «PinCode» dans votre Excel. Cela ne fonctionnerait pas ci-dessous, il faudrait que ce soit «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

Pour l'exemple d'entrée que vous avez donné ci-dessus, ce code sort:

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

Et parce que je suis un python noob, les accessoires sont à: cette réponse , cette réponse , cette question , cette question et cette réponse .


Je pense que firstRow[x].valuec'est censé êtreheaderRow[x].value
TSeymour

0

Bien que j'utilise presque toujours des pandas pour cela, mon petit outil actuel est emballé dans un exécutable et inclure des pandas est excessif. J'ai donc créé une version de la solution de poida qui a abouti à une liste de tuples nommés. Son code avec ce changement ressemblerait à ceci:

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)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.