2013-12-10 27 views
5

Có cách nào dễ dàng để có được một khung dữ liệu gấu trúc từ một phạm vi được đặt tên trong excel hay không. Read_excel được thiết kế để đọc toàn bộ trang tính trong một sổ làm việc.Pandas dataframe từ excel có tên là

Trả lời

0

Bạn có thể làm điều này trong một vòng về cách sử dụng read_excel, nó cung cấp:

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”) 

Điều này có nghĩa nếu bạn biết tên cột và số dòng (? Có lẽ những gì bạn có ý nghĩa bởi "phạm vi có tên là") bạn có thể chọn phần đó để tạo DataFrame.

+0

này cho phép bạn bỏ qua các hàng ngay từ đầu. Nó sẽ vẫn đọc cho đến khi ô trống cuối cùng trong trang tính. –

+0

Kiểm tra DataNitro. Đó là một sự bổ sung tuyệt vời cho excel cho phép chính xác loại điều này cũng như nhiều thứ khác. Miễn phí cho các dự án phi thương mại. Tôi sử dụng nó rộng rãi –

+0

@ David không phải là điểm của skip_footer? (Tôi đồng ý điều này có thể làm với một chức năng wrapper tốt đẹp ..) –

1

Để trích dẫn Microsoft Office help pages:

A [tên phạm vi] là một cách viết tắt có ý nghĩa mà làm cho nó dễ dàng hơn để hiểu mục đích của một tham chiếu ô, liên tục, công thức, hoặc bảng, mỗi trong số đó có thể khó hiểu ngay từ cái nhìn đầu tiên. "

Phạm vi được đặt tên thường được sử dụng trong bảng tính để truy cập dữ liệu dễ dàng hơn thông qua ODBC và đặc biệt hữu ích khi có một số phạm vi dữ liệu trong cùng một trang tính. chỉ cần chọnthích hợp 0 và gửi câu lệnh SQL, ví dụ:

SELECT * 
FROM namedRange 

Lệnh hữu ích trong Pandas có lẽ sẽ là read_sql. Tuy nhiên, giải pháp này yêu cầu bạn căn chỉnh/sắp xếp hợp lý các phiên bản phần mềm đã cài đặt (32 bit hoặc 64 bit) của Excel, trình điều khiển ODBC và gói phần mềm mà từ đó bạn mở kết nối ODBC. Ví dụ, một phiên bản Excel 32-bit được cài đặt sẽ yêu cầu trình điều khiển ODBC 32 bit và thường là cài đặt Python 32 bit. Lưu ý: điểm sau này vẫn được xác nhận cho trường hợp Python (tôi là người mới bắt đầu với Python), nhưng tôi chắc chắn có thể xác nhận điểm này cho các kết nối ODBC được khởi chạy từ SAS, SPSS hoặc Stata.

Yêu cầu trước đó là một nhược điểm rất quan trọng và thực sự nói có lợi cho bất kỳ giải pháp nào không liên quan đến ODBC. Điều đó nói rằng, nó sẽ là tốt đẹp nếu read_Excel cung cấp một cơ sở như vậy. Trong bối cảnh này, thật thú vị khi lưu ý rằng SAS, SPSS và Stata hiện không cho phép truy cập trực tiếp vào các dải ô được đặt tên trong bộ lọc Excel tương ứng của chúng - vì vậy có thể là có một lý do khách quan cho tính năng thiếu ...

1

Bạn có thể sử dụng gói xlrd bên dưới để thực hiện việc này.

Gói xlrd đi kèm với thư mục examples có chứa xlrdnameAPIdemo.py, như được ghi trong tài liệu here.

Tóm lại cho tên phạm vi print_area thử:

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

Bạn sẽ thấy name_obj có một mục:

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

mà bạn có thể làm theo các ví dụ để giải thích, mặc dù nó doesn' t nhìn đơn giản - ví dụ. phạm vi có thể tương đối hay không, tùy thuộc vào giá trị result.kind.

Hơn nữa, khi tôi cố gắng sử dụng tính năng này để đọc bảng tính của riêng mình (được tạo trên máy Mac), tôi thấy resultNone; thay vào đó, các ref chỉ phạm vi trong name_obj là:

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

Vì vậy, có thể có một cách để làm công việc này trong một trường hợp chung, nhưng có vẻ như nó sẽ mất một số thử và sai. Thay vào đó, nếu bạn có thể định dạng bảng tính của mình để thay vì các dải ô được đặt tên, bảng của bạn sẽ theo sau các hàng ngay sau một tiêu đề duy nhất (key) và kết thúc bằng một hàng trống, đây là một hàm tìm thấy thông số thích hợp để gửi đến 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) 

Nếu bạn làm theo điều này với một pd.read_excel sau đó bạn đang đọc các tập tin dữ liệu hai lần, đó là ngớ ngẩn, nhưng bạn sẽ có được ý tưởng.

0

Có thể gấu trúc một ngày nào đó sẽ hỗ trợ điều này một cách tự nhiên. Cho đến lúc đó, tôi sử dụng một hàm helper:

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

Dưới đây là cách tôi sử dụng openpyxl để sao chép một loạt trong một [[]]:

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