2015-06-08 4 views
1

Я пытаюсь сделать невероятно простую вещь: загружать части листа Excel в массив Numpy. Я нашел кладж, который работает, но это ошеломляюще unpythonic: сказать, что мой рабочий лист был загружен как «WS», код:Рабочий лист Excel для массива Numpy

A = np.zeros((37,3)) 
for i in range(2,39): 
    for j in range(1,4): 
     A[i-2,j-1]= ws.cell(row = i, column = j).value 

загружает содержимое «WS» в массиве А.

Должен быть более элегантный способ сделать это. Например, csvread позволяет сделать это гораздо более естественно, и хотя я мог бы преобразовать файл .xlsx в csv, вся цель работы с openpyxl состояла в том, чтобы избежать этого преобразования. Итак, вот мы, Коллективная Мудрость Могучих Интертруб: что более питонический способ выполнить эту концептуально тривиальную операцию?

Заранее благодарю вас за ответы.

PS: Я управляю Python 2.7.5 на Mac через Spyder, и да, я прочитал учебник openpyxl, и это единственная причина, по которой я получил это.

ответ

4

Вы могли бы сделать

A = np.array([[i.value for i in j] for j in ws['C1':'E38']]) 

EDIT - дальнейшее объяснение. (во-первых, спасибо за представляя меня openpyxl, я подозреваю, что я буду использовать его совсем немного время от времени)

  1. метод получения нескольких ячеек от объекта рабочего листа производит генератор. Это, вероятно, намного эффективнее, если вы хотите проложить свой путь через большой лист, так как вы можете начать сразу же, не дожидаясь, пока все это загрузится в ваш список.
  2. , чтобы заставить генератор, чтобы сделать список, вы можете использовать list(ws['C1':'E38']) или список понимание, как указано выше
  3. каждая строка представляет собой кортеж (даже если только один столбец шириной) из
  4. объектов Cell. Они имеют гораздо больше о них, чем просто число, но если вы хотите получить номер для своего массива, вы можете использовать атрибут .value. Это действительно суть вашего вопроса, csv-файлы не содержат структурированную информацию о Excel-таблице.
  5. нет (насколько я могу судить) встроенного метода для извлечения значений из диапазона ячеек, поэтому вам нужно будет сделать что-то эффективно, как вы набросали.

Преимущества этого в моем способе: нет необходимости выработать измерение массива и сделать пустым, с чего начать, не нужно выработать исправленный индексный номер массива np, запомнить список Быстрее. Недостатком является то, что ему нужны «углы», определяющие формат «A1». Если диапазон не знаете, то вам придется использовать iter_rows, строки или столбцы

A = np.array([[i.value for i in j[2:5]] for j in ws.rows]) 

, если вы не знаете, сколько столбцов, то вы должны цикла и проверить значения больше как вашей оригинальной идеи

+0

Спасибо. Это, бесспорно, более элегантно. Не могли бы вы объяснить, какие понятия здесь задействованы? Я думаю, что я понимаю стиль цикла, который вы используете (я видел, как он применялся к целому или список элементов), но мне трудно понять, как перебирать элементы ws []. Например, если я набираю тип (ws ['C1']), я получаю openpyxl.cell.cell.Cell, и для меня совершенно не очевидно, как можно перебирать этот объект. Я пытаюсь научиться лучше программировать, а не просто задавать вопросы по StackOverflow ... Спасибо за ваше терпение. –

+0

@ ElNiño есть несколько вещей, я отредактирую свой ответ и добавлю немного больше информации. – paddyg

+0

Aaaah, «понимание списка». Так называется этот волшебный трюк? Я немного почитал об этом. Для того, чтобы привыкнуть к нему, потребуется переформатирование мозга, но оно выглядит очень мощным. Таким образом, в этом случае он знает, что цикл с использованием генератора, встроенного в ws? Мне пришлось искать «генератор» тоже. В любом случае, спасибо за советы, и рад, что я могу указать вам на один полезный пакет, который я не писал! –

1

Если вам не нужно загружать данные из нескольких файлов автоматическим способом, пакет tableconvert, который я недавно написал, может помочь. Просто скопируйте и вставьте соответствующие ячейки из файла excel в многострочную строку и используйте функцию convert().

import numpy as np 
from tableconvert.converter import convert 

array = convert(""" 
123 456 3.14159 
SOMETEXT 2,71828 0 
""") 

print(type(array)) 
print(array) 

Выход:

<class 'numpy.ndarray'> 
[[ 123.  456.   3.14159] 
[  nan 2.71828 0.  ]] 
Смежные вопросы