web-dev-qa-db-fra.com

Lire un fichier Excel en Python

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 veux enregistrer une chaîne sous la forme Arm_id,DSPCode,Pincode. Ce format est configurable, c’est-à-dire qu’il pourrait changer en DSPCode,Arm_id,Pincode. Je sauvegarde le format 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 FORMAT est 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']]

Puis je boucle autour de values[0] en essayant de trouver le contenu FORMAT dans values[0], puis en obtenant l'index de Arm_id, DSPname and Pincode dans le values[0], puis dans la boucle suivante, je connais l'index de tous les facteurs FORMAT, ce qui me permet de savoir quelle valeur dois-je obtenir .

Mais c'est une si mauvaise solution.

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

68
PythonEnthusiast

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(). Cependant, si vous utilisez une classe, 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
62
tamasgal

Une réponse un peu tardive, mais avec les pandas, il est possible d'obtenir directement une colonne d'un fichier Excel:

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]
74
sheinis

Les parties clés doivent donc saisir l'en-tête (col_names = s.row(0)) et, lors d'une itération, parcourir les lignes, ignorer la première ligne qui n'est pas nécessaire for row in range(1, s.nrows) - en utilisant une plage de 1 et plus (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
10
Noel Evans

En utilisant des pandas, nous pouvons facilement lire Excel.

import pandas as pd 
import xlrd as xl 
from pandas import ExcelWriter
from pandas import ExcelFile 

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

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

Testez à: https://repl.it Référence: https://pythonspot.com/read-Excel-with-pandas/

5
Mahabubuzzaman

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 exportées 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 colonne dans la liste FORMAT.

Dans mon code ci-dessous, la casse du nom de la colonne dans la liste FORMAT est importante. Dans la question ci-dessus, vous avez 'Pincode' dans votre liste de 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 affiche:

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

Et comme je suis un noob python, les accessoires doivent être: cette réponse , cette réponse , cette question , cette questionet cette réponse .

1
poida

Voici le code pour lire un fichier Excel et pour imprimer toutes les cellules présentes dans la colonne 1 (à l’exception de 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))
0
harsha vardhan

Bien que j'utilise presque toujours des pandas pour cela, mon petit outil actuel est intégré à un exécutable et les pandas sont excessifs. 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)
0
TSeymour