2013-12-10 60 views

回答

0

您可以在周圍使用read_excel的方式做到這一點,它提供:

skiprows : list-like 
    Rows to skip at the beginning (0-indexed) 

skip_footer : int, default 0 
    Rows at the end to skip (0-indexed) 

parse_cols : int or list, default None 
     If None then parse all columns, 
     If int then indicates last column to be parsed 
     If list of ints then indicates list of column numbers to be parsed 
     If string then indicates comma separated list of column names and column ranges (e.g. 「A:E」 or 「A,C,E:F」) 

這意味着,如果你知道列名和行號(?想必你所說的「命名的範圍」的意思)您可以只選擇該部分來製作DataFrame。

+0

這可以讓你在一開始跳過行。它仍會讀取直到表單中最後一個空單元。 –

+0

檢出DataNitro。對於excel來說,它是一個非常好的補充,它允許這樣的事情以及許多其他事情。它免費用於非商業項目。我廣泛使用 –

+0

@DavidNehme是不是skip_footer的重點? (我同意這可以做一個漂亮的包裝函數..) –

1

引述Microsoft Office help pages

A [命名範圍]是一個有意義的速記,使得它更容易理解單元格引用,恆定,公式或表的目的,其中的每一個可以是難以乍一看理解。」

命名區域被進一步頻繁地通過ODBC電子表格來更容易獲得的數據使用,並且當有相同的工作表內的多個數據的範圍內。爲了通過ODBC連接到Excel是特別有用的,只需選擇合適的即可0併發送SQL語句,例如:

SELECT * 
FROM namedRange 

Pandas中的有用命令可能是read_sql。

在Windows中,此解決方案需要您對齊/精簡Excel的已安裝軟件版本(32位或64位),ODBC驅動程序和從中打開ODBC連接的軟件包。例如,已安裝的Excel 32位版本將需要32位ODBC驅動程序,通常是32位的Python安裝。 注意:後面一點對Python的情況(我是Python的初學者)還有待證實,但我可以肯定地證實從SAS,SPSS或Stata啓動的ODBC連接的這一點。

以前的要求是一個非常明顯的缺點,並且實際上對任何完全不涉及ODBC的解決方案都表示支持。也就是說,如果read_Excel提供了這樣的設施,那將會很好。在這種情況下,值得注意的是,SAS,SPSS和Stata目前不允許直接訪問各自Excel過濾器中的命名範圍 - 因此這個缺乏功能的客觀原因是...

1

你可以使用底層的xlrd包來做到這一點。

xlrd包帶有一個examples目錄,其中包含xlrdnameAPIdemo.py,如記錄here

在已命名的範圍print_area嘗試一言以蔽之:

book = xlrd.open_workbook('examples/namesdemo.xls') 
name_obj = book.name_map['print_area'][0] 
print name_obj.__dict__ 

你會看到name_obj有一個條目:

'result': Operand(kind=oREF, value=[Ref3D(coords=(2, 3, 0, 4, 0, 14))], text=u'Sheet3!$A$1:$N$4') 

,你可以按照示例解釋,雖然它不」看起來很簡單 - 例如。範圍可能相對與否,取決於值result.kind。此外,當我試圖用這個閱讀我自己的電子表格(在Mac上創建)時,我發現resultNone;相反,只有裁判在name_obj範圍爲:

'formula_text': u'Sheet1!$B$6:$E$11' 

所以有可能是一種方法,使在一般情況下,這個工作,但它看起來像它會採取一些試驗和錯誤。

作爲一種替代方法,如果您可以設置電子表格的格式而不是命名範圍,那麼表格緊跟在唯一標題(key)後面的行中,並以空行結束,這裏是一個函數,它可以找到正確的參數發送給pd.read_excel

def table_position(path, sheet_name, key): 
    """ 
    Find the start and end rows of a table in an Excel spreadsheet 
    based on the first occurence of key text on the sheet, and down 
    to the first blank line. 

    Returns (col, start_row, end_row, skip_footer) 

    where: 
     col is the column number containing the key text, 
     start_row is the row after this, 
     end_row is the row number of the next blank line, 
     skip_footer is how many rows from the end of the sheet this is. 

    You can then read in the table with: 
     x = pd.read_excel(path, sheet_name, skiprows=start, skip_footer=skip_footer, header=0) 
     x = x.dropna(axis=1, how='all') 
    """ 
    import xlrd 
    book = xlrd.open_workbook(path) 
    sheet = book.sheet_by_name(sheet_name) 
    # find the first occurrence of the key, and the next line break 
    (col, start, end) = (-1, -1, sheet.nrows) 
    for rownum in xrange(sheet.nrows): 
     if col<0: # look for key to start the table off 
      try: 
       test_col = next(c for c in xrange(sheet.ncols) if sheet.cell(rownum, c).value==key) 
      except StopIteration: 
       pass 
      else: 
       col, start = test_col, rownum+1 # row after key text is the start 
     else: # test for blank line as end of table 
      if not [True for cell in sheet.row(rownum) if cell.value]: 
       end = rownum 
       break 
    skip_footer = sheet.nrows - end 
    return (col, start, end, skip_footer) 

如果按照這個有pd.read_excel那麼你正在閱讀兩倍的數據文件,這是愚蠢的,但你的想法。

0

也許有一天熊貓會支持這個本地。在那之前,我使用一個輔助功能:

import pandas as pd 
import openpyxl 

def data_frame_from_xlsx(xlsx_file, range_name): 
    """ Get a single rectangular region from the specified file. 
    range_name can be a standard Excel reference ('Sheet1!A2:B7') or 
    refer to a named region ('my_cells').""" 
    wb = openpyxl.load_workbook(xlsx_file, data_only=True, read_only=True) 
    if '!' in range_name: 
     # passed a worksheet!cell reference 
     ws_name, reg = range_name.split('!') 
     if ws_name.startswith("'") and ws_name.endswith("'"): 
      # optionally strip single quotes around sheet name 
      ws_name = ws_name[1:-1] 
     region = wb[ws_name][reg] 
    else: 
     # passed a named range; find the cells in the workbook 
     full_range = wb.get_named_range(range_name) 
     if full_range is None: 
      raise ValueError(
       'Range "{}" not found in workbook "{}".'.format(range_name, xlsx_file) 
      ) 
     # convert to list (openpyxl 2.3 returns a list but 2.4+ returns a generator) 
     destinations = list(full_range.destinations) 
     if len(destinations) > 1: 
      raise ValueError(
       'Range "{}" in workbook "{}" contains more than one region.' 
       .format(range_name, xlsx_file) 
      ) 
     ws, reg = destinations[0] 
     # convert to worksheet object (openpyxl 2.3 returns a worksheet object 
     # but 2.4+ returns the name of a worksheet) 
     if isinstance(ws, str): 
      ws = wb[ws] 
     region = ws[reg] 
    df = pd.DataFrame([cell.value for cell in row] for row in region) 
    return df 
0

下面是我用openpyxl在[[]]複製範圍的方式:

wb = load_workbook(filename=xlPath) 
ws, range= next(wb.defined_names["rangename"].destinations) 
materials = [[cell.value for cell in row] for row in wb[ws][range]]