salida - Lea el archivo de Excel en Python
trabajar con archivos excel en python (6)
Tengo un archivo de 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
Quiero guardar una cadena con el formato Arm_id,DSPCode,Pincode
. Este formato es configurable, es decir, podría cambiar a DSPCode,Arm_id,Pincode
. Lo guardo formato en una lista como
FORMAT = [''Arm_id'', ''DSPName'', ''Pincode'']
¿Cómo leo el contenido de una columna específica con el nombre proporcionado, dado que el FORMAT
es configurable?
Esto es lo que intenté. Actualmente puedo leer todo el contenido del archivo
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
Mi salida es
[[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'']]
Luego recorro values[0]
tratando de descubrir el contenido FORMAT
en values[0]
y luego Arm_id, DSPname and Pincode
el índice de Arm_id, DSPname and Pincode
en los values[0]
y luego del siguiente ciclo sé el índice de todos los FORMAT
factores, por lo tanto, llegar a saber qué valor necesito obtener.
Pero esta es una solución tan pobre.
¿Cómo obtengo los valores de una columna específica con nombre en el archivo Excel?
Al usar pandas, podemos leer Excel fácilmente.
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)
Prueba en: https://repl.it Referencia: https://pythonspot.com/read-excel-with-pandas/
Aunque casi siempre solo uso pandas para esto, mi pequeña herramienta actual está siendo empaquetada en un ejecutable e incluir los pandas es exagerado. Así que creé una versión de la de que dio como resultado una lista de tuplas con nombre. Su código con este cambio se vería así:
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)
El enfoque que tomé lee la información del encabezado de la primera fila para determinar los índices de las columnas de interés.
Usted mencionó en la pregunta que también quiere que los valores se envíen a una cadena. Construyo dinámicamente una cadena de formato para el resultado de la lista de columnas FORMATO. Las filas se añaden a la cadena de valores separada por una nueva línea de caracteres.
El orden de las columnas de salida se determina por el orden de los nombres de las columnas en la lista FORMAT.
En mi código a continuación, el caso del nombre de la columna en la lista FORMATO es importante. En la pregunta anterior tienes ''Pincode'' en tu lista de FORMAT, pero ''PinCode'' en tu Excel. Esto no funcionaría a continuación, necesitaría ser ''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
Para la entrada de muestra que proporcionó anteriormente este código muestra:
>>> 1.0,JaVAS,282001.0
2.0,JaVAS,282002.0
3.0,JaVAS,282003.0
Y como soy un novato de Python, los accesorios son para: esta respuesta , esta respuesta , esta pregunta , esta pregunta y esta respuesta .
Entonces las partes clave son agarrar el encabezado ( col_names = s.row(0)
) y al iterar a través de las filas, omitir la primera fila que no es necesaria for row in range(1, s.nrows)
- hecho por usando un rango de 1 en adelante (no el 0 implícito). A continuación, usa zip para recorrer las filas con "nombre" como encabezado de la columna.
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
Este es un enfoque:
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
No tiene que usar una clase personalizada, simplemente puede tomar un dict()
. Sin embargo, si usa una clase, puede acceder a todos los valores mediante notación de puntos, como puede ver arriba.
Aquí está el resultado del script anterior:
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
Una respuesta algo tardía, pero con los pandas es posible obtener directamente una columna de un archivo de 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]