Хранение столбцов таблицы в словарь Python

у меня есть таблица, хранящаяся в файле Excel следующим образом:

Species     Garden Hedgerow Parkland Pasture Woodland
Blackbird       47       10      40        2        2
Chaffinch       19        3       5        0        2
Great Tit       50        0      10        7        0
House Sparrow   46       16       8        4        0
Robin            9        3       0        0        2
Song Thrush      4        0       6        0        0

я использую xlrd библиотека Python для чтения этих данных. У меня нет проблем с чтением его в список списков (с каждой строкой таблицы, хранящейся как список), используя код ниже:

from xlrd import open_workbook
wb = open_workbook("Sample.xls")
headers = []
sdata = []
for s in wb.sheets():
    print "Sheet:",s.name
    if s.name.capitalize() == "Data":
        for row in range(s.nrows):
            values = []
            for col in range(s.ncols):
                data = s.cell(row,col).value
                if row == 0:
                    headers.append(data)
                else:   
                    values.append(data)
            sdata.append(values)

как, вероятно, очевидно,headers это простой список, хранящий заголовки столбцов и sdata содержит табличные данные, хранящиеся в виде списка списков. Вот что они смотри:

заголовки:

[u'Species', u'Garden', u'Hedgerow', u'Parkland', u'Pasture', u'Woodland']

sdata:

[[u'Blackbird', 47.0, 10.0, 40.0, 2.0, 2.0], [u'Chaffinch', 19.0, 3.0, 5.0, 0.0, 2.0], [u'Great Tit', 50.0, 0.0, 10.0, 7.0, 0.0], [u'House Sparrow', 46.0, 16.0, 8.0, 4.0, 0.0], [u'Robin', 9.0, 3.0, 0.0, 0.0, 2.0], [u'Song Thrush', 4.0, 0.0, 6.0, 0.0, 0.0]]

но я хочу сохранить эти данные в словаре Python, с каждым столбцом в качестве ключа для списка, содержащего все значения для каждого столбца. Например (для экономии места показана только часть данных):

dict = {
    'Species': ['Blackbird','Chaffinch','Great Tit'], 
    'Garden': [47,19,50], 
    'Hedgerow': [10,3,0], 
    'Parkland': [40,5,10], 
    'Pasture': [2,0,7], 
    'Woodland': [2,2,0]
} 

Итак, мой вопрос: как я могу добиться этого? Я знаю, что могу читать данные по столбцам, а не по строкам, как в приведенном выше фрагменте кода, но я не мог понять, как сохранить столбцы в словаре.

заранее спасибо за любую помощь вы можете предоставить.

5 ответов


если у вас есть столбцы, это довольно легко:

dict(zip(headers, sdata))

на самом деле, это выглядит как sdata в вашем примере могут быть данные строки, даже если это все еще довольно просто, вы можете транспонировать таблицу с помощью zip а также:

dict(zip(headers, zip(*sdata)))

один из этих двух является то, что вы просите.


1 . XLRD

я настоятельно рекомендую использовать defaultdict от коллекции библиотека. Значение каждого ключа будет инициировано со значением по умолчанию, пустым списком в этом случае. Я не ставил там много исключений, вы можете добавить обнаружение исключений на основе вашего варианта использования.

import xlrd
import sys
from collections import defaultdict
result = defaultdict(list)
workbook = xlrd.open_workbook("/Users/datafireball/Desktop/stackoverflow.xlsx")
worksheet = workbook.sheet_by_name(workbook.sheet_names()[0])

headers = worksheet.row(0)
for index in range(worksheet.nrows)[1:]:
    try:
        for header, col in zip(headers, worksheet.row(index)):
            result[header.value].append(col.value)
    except:
        print sys.exc_info()

print result

выход:

defaultdict(<type 'list'>, 
{u'Garden': [47.0, 19.0, 50.0, 46.0, 9.0, 4.0], 
u'Parkland': [40.0, 5.0, 10.0, 8.0, 0.0, 6.0], 
u'Woodland': [2.0, 2.0, 0.0, 0.0, 2.0, 0.0], 
u'Hedgerow': [10.0, 3.0, 0.0, 16.0, 3.0, 0.0], 
u'Pasture': [2.0, 0.0, 7.0, 4.0, 0.0, 0.0], 
u'Species': [u'Blackbird', u'Chaffinch', u'Great Tit', u'House Sparrow', u'Robin', u'Song Thrush']})

2 . Панды!--5-->

import pandas as pd
xl = pd.ExcelFile("/Users/datafireball/Desktop/stackoverflow.xlsx")
df = xl.parse(xl.sheet_names[0])
print df

выход, и вы не можете себе представить, сколько гибкости вы можете получить используя таблицу данных.

             Species  Garden  Hedgerow  Parkland  Pasture  Woodland
0      Blackbird      47        10        40        2         2
1      Chaffinch      19         3         5        0         2
2      Great Tit      50         0        10        7         0
3  House Sparrow      46        16         8        4         0
4          Robin       9         3         0        0         2
5    Song Thrush       4         0         6        0         0

я внесу свой вклад, предоставив еще один ответ на мой собственный вопрос!

сразу после того, как я опубликовал свой вопрос, я узнал pyexcel -- довольно маленькая библиотека Python, которая действует как оболочка для других пакетов обработки электронных таблиц (а именно, xlrd и odfpy). Он имеет хороший метод to_dict, который делает именно то, что я хочу (даже без необходимости транспонировать таблицу)!

вот пример, используя данные сверху:

from pyexcel import SeriesReader
from pyexcel.utils import to_dict

sheet = SeriesReader("Sample.xls")
print sheet.series() #--- just the headers, stored in a list
data = to_dict(sheet)
print data #--- the full dataset, stored in a dictionary

выход:

u'Species', u'Garden', u'Hedgerow', u'Parkland', u'Pasture', u'Woodland']
{u'Garden': [47.0, 19.0, 50.0, 46.0, 9.0, 4.0], u'Hedgerow': [10.0, 3.0, 0.0, 16.0, 3.0, 0.0], u'Pasture': [2.0, 0.0, 7.0, 4.0, 0.0, 0.0], u'Parkland': [40.0, 5.0, 10.0, 8.0, 0.0, 6.0], u'Woodland': [2.0, 2.0, 0.0, 0.0, 2.0, 0.0], u'Species': [u'Blackbird', u'Chaffinch', u'Great Tit', u'House Sparrow', u'Robin', u'Song Thrush']}

надеюсь, что это помогает!


Если XLRD не решит вашу проблему, подумайте о том, чтобы посмотреть на XLWings. В одном из примеров видео показано, как взять данные из таблицы Excel и импортировать их в фрейм данных Pandas, который будет более полезен, чем словарь.

Если вы действительно хотите словарь, панды могут легко конвертировать в это, см. здесь.


этот скрипт позволяет преобразовать данные excel в список словарных

import xlrd

workbook = xlrd.open_workbook('Sample.xls')
workbook = xlrd.open_workbook('Sample.xls', on_demand = True)
worksheet = workbook.sheet_by_index(0)
first_row = [] # The row where we stock names of columns
for col in range(worksheet.ncols):
    first_row.append( worksheet.cell_value(0,col) )
# tronsform the workbook to a list of dictionnary
data =[]
for row in range(1, worksheet.nrows):
    elm = {}
    for col in range(worksheet.ncols):
        elm[first_row[col]]=worksheet.cell_value(row,col)
    data.append(elm)
print data