Leggi il file Excel in Python


88

Ho un file 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

Voglio salvare una stringa nel modulo Arm_id,DSPCode,Pincode. Questo formato è configurabile, cioè potrebbe cambiare in DSPCode,Arm_id,Pincode. Lo salvo in una lista come:

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

Come leggo il contenuto di una specifica colonna con il nome fornito, dato che FORMATè configurabile?

Questo è quello che ho provato. Al momento sono in grado di leggere tutto il contenuto del file

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

La mia uscita è

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

Quindi giro in giro values[0]cercando di scoprire il FORMATcontenuto values[0]e quindi ottenere l'indice di Arm_id, DSPname and Pincodenel values[0]ciclo successivo e poi dal prossimo ciclo conosco l'indice di tutti i FORMATfattori, arrivando così a sapere quale valore devo ottenere.

Ma questa è una soluzione così scadente.

Come ottengo i valori di una colonna specifica con il nome nel file excel?


È necessario utilizzare dict()o creare la propria classe di dati.
tamasgal

Come come? potete fornire un codice di esempio?
PythonEnthusiast

Risposte:


71

Questo è un approccio:

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

Non devi usare una classe personalizzata, puoi semplicemente prendere un file dict(). Se usi una classe, tuttavia, puoi accedere a tutti i valori tramite la notazione a punti, come vedi sopra.

Ecco l'output dello script sopra:

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

Una risposta un po 'tardiva, ma con i panda è possibile ottenere direttamente una colonna di un file 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]

Assicurati di aver installato xlrd e panda:

pip install pandas xlrd

2
Aggiungi import xlrdin alto per farlo funzionare. read_excelrichiede xlrd. Se ImportError: No module named 'xlrd'lo pip install xlrd
ottieni

9
l'importazione di xlrd non è richiesta, assicurati solo che xlrd sia installato, i panda lo importeranno e lo useranno.
Vaibhav Vishal

12

Quindi le parti chiave sono afferrare l'intestazione ( col_names = s.row(0)) e durante l'iterazione tra le righe, saltare la prima riga che non è necessaria for row in range(1, s.nrows)- fatto utilizzando l'intervallo da 1 in poi (non lo 0 implicito). Quindi utilizza zip per scorrere le righe che contengono "nome" come intestazione della colonna.

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

Ecco il codice per leggere un file excel e stampare tutte le celle presenti nella colonna 1 (tranne la prima cella ovvero l'intestazione):

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'approccio che ho adottato legge le informazioni di intestazione dalla prima riga per determinare gli indici delle colonne di interesse.

Nella domanda hai menzionato che vuoi anche che i valori vengano visualizzati in una stringa. Creo dinamicamente una stringa di formato per l'output dall'elenco di colonne FORMAT. Le righe vengono aggiunte alla stringa dei valori separate da una nuova riga char.

L'ordine delle colonne di output è determinato dall'ordine dei nomi delle colonne nell'elenco FORMAT.

Nel mio codice sottostante è importante il caso del nome della colonna nell'elenco FORMAT. Nella domanda sopra hai "Pincode" nella tua lista FORMAT, ma "PinCode" nel tuo Excel. Questo non funzionerebbe sotto, dovrebbe essere "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

Per l'input di esempio che hai fornito sopra, questo codice genera:

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

E poiché sono un noob in pitone, gli oggetti di scena sono: questa risposta , questa risposta , questa domanda , questa domanda e questa risposta .


Penso che firstRow[x].valuedovrebbe essereheaderRow[x].value
TSeymour

0

Sebbene io usi quasi sempre i panda per questo, il mio piccolo strumento attuale viene impacchettato in un eseguibile e includere i panda è eccessivo. Così ho creato una versione della soluzione di poida che ha prodotto un elenco di tuple con nome. Il suo codice con questa modifica sarebbe simile a questo:

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.