Excel Dosyasını Python'da Okuyun


88

Excel Dosyam var

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

Formdaki bir dizeyi kaydetmek istiyorum Arm_id,DSPCode,Pincode. Bu format yapılandırılabilir, yani olarak değişebilir DSPCode,Arm_id,Pincode. Onu şöyle bir listeye kaydediyorum:

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

FORMATYapılandırılabilir olduğu düşünüldüğünde, verilen adla belirli bir sütunun içeriğini nasıl okuyabilirim ?

Ben bunu denedim. Şu anda dosyadaki tüm içeriği okuyabiliyorum

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

Çıktım

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

Etrafında Sonra döngü values[0]bulmaya çalışıyorlar FORMATiçeriği values[0]dizinini alma sonra ve Arm_id, DSPname and Pincodede values[0]ardından gelecek döngüden tüm dizinini bilmeniz FORMATböylece ben almak gerekir hangi değer tanımaya faktörler.

Ancak bu çok kötü bir çözüm.

Excel dosyasında adı olan belirli bir sütunun değerlerini nasıl alırım?


Ya bir kullanmalı dict()ya da kendi veri sınıfınızı oluşturmalısınız.
tamasgal

Ne gibi? lütfen bir örnek kod verebilir misiniz?
PythonEnthusiast

Yanıtlar:


71

Bu bir yaklaşımdır:

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

Özel bir sınıf kullanmak zorunda değilsiniz, basitçe bir dict(). Ancak bir sınıf kullanıyorsanız, yukarıda gördüğünüz gibi tüm değerlere noktalı gösterim yoluyla erişebilirsiniz.

İşte yukarıdaki komut dosyasının çıktısı:

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

Biraz geç bir cevap, ancak pandalarda doğrudan bir excel dosyasının bir sütununu almak mümkündür:

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]

Xlrd ve pandaları yüklediğinizden emin olun:

pip install pandas xlrd

2
import xlrdBunun işe yaraması için en üste ekleyin . read_excelgerektirir xlrd. Alma durumunda ImportError: No module named 'xlrd', o zaman yapmakpip install xlrd
nishant

9
xlrd'yi içe aktarmak gerekli değildir, yalnızca xlrd'nin kurulu olduğundan emin olun, pandalar bunu içe aktaracak ve kullanacaktır.
Vaibhav Vishal

12

Bu yüzden anahtar kısımlar başlığı ( col_names = s.row(0)) kapmak ve satırlar arasında yineleme yaparken, gerekli olmayan ilk satırı atlamaktır for row in range(1, s.nrows)- 1'den sonraki aralık kullanılarak yapılır (örtük 0 değil). Ardından, sütunun başlığı olarak 'ad'ı tutan satırlarda gezinmek için zip'i kullanın.

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

İşte bir excel dosyasını okumak ve 1. sütunda bulunan tüm hücreleri yazdırmak için kod (ilk hücre, yani başlık hariç):

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

Benim aldığım yaklaşım, ilgilenilen sütunların indekslerini belirlemek için ilk satırdan başlık bilgilerini okur.

Soruda, değerlerin bir dizeye çıktısını da istediğinizi belirtmiştiniz. FORMAT sütun listesinden çıktı için dinamik olarak bir biçim dizesi oluşturuyorum. Yeni bir satır karakteriyle ayrılmış değerler dizesine satırlar eklenir.

Çıktı sütun sırası, FORMAT listesindeki sütun adlarının sırasına göre belirlenir.

Aşağıdaki kodumda, FORMAT listesindeki sütun adının durumu önemlidir. Yukarıdaki soruda FORMAT listenizde 'Pincode', excelinizde 'PinCode' var. Bu aşağıda çalışmaz, 'PinCode' olması gerekir.

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

Yukarıda verdiğiniz örnek giriş için şu kod çıktıları:

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

Ve ben bir python noob olduğum için, bu cevap , bu cevap , bu soru , bu soru ve bu cevap .


Sanırım firstRow[x].valueşöyle olmalıheaderRow[x].value
TSeymour

0

Neredeyse her zaman bunun için sadece pandaları kullansam da, şu anki küçük aracım bir yürütülebilir dosya olarak paketleniyor ve pandaları da dahil etmek çok fazla. Ben de poida'nın çözümünün bir adlandırılmış tuple listesi ile sonuçlanan bir sürümünü yarattım . Bu değişiklikle birlikte kodu şöyle görünecektir:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.