2015-06-08 30 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”的内容到阵列A.

必须有一个更优雅的方式来做到这一点。例如,csvread允许更自然地做到这一点,虽然我可以很好地将.xlsx文件转换为csv文件,但使用openpyxl的目的是避免转换。那么我们就是,强大Intertubes的集体智慧:执行这个概念上微不足道的操作的更多pythonic方法是什么?

非常感谢您的回答。 PS:我通过Spyder在Mac上运行Python 2.7.5,是的,我读过了openpyxl教程,这是我得到这个目标的唯一原因。

回答

4

你可以做

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

编辑 - 进一步的解释。 (首先感谢把我介绍给openpyxl,我怀疑我会用它的时间相当多的时间)

  1. 从工作表对象越来越多的细胞的方法产生的发电机。如果你想在大型工作表中工作,这可能会更有效率,因为你可以立即开始工作,而无需等待全部加载到列表中。
  2. 迫使发电机以使列表既可以使用list(ws['C1':'E38'])或列表理解如上
  3. 每一行是一个元组(即使只有一列宽)
  4. 细胞的对象。这些有很多关于它们的信息,而不仅仅是一个数字,但如果你想获得数组的数字,你可以使用.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 []元素。例如,如果我键入type(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.  ]]