2017-01-31 13 views
1

私はデータベースに解析し、書き込むことを試みているひどくレイアウトされたExcelシートを扱っています。多くのテーブルを持つExcelシートからデータフレームを解析する方法(Python、おそらくPandasを使用)

すべてのシートは複数のテーブルを持つことができます。これらの可能なテーブルのヘッダーはわかっていますが、特定のシート上にあるテーブルはそうではありませんし、シート上の正確な位置も同じではありません(テーブルは一貫した方法で整列しません)。これを説明するために2つのシートレイアウトを追加しました。This layoutには2つのテーブルがあり、this oneには最初のテーブルがありますが、同じ場所にはありません。私が知っている何

  1. すべての可能なテーブルのヘッダは、その個々のテーブルには、
  2. テーブルが空白のセルで区切られ、そのヘッダで識別することができます。彼らはお互いに触れません。

私の質問パンダのようなPythonモジュールを使ってこの問題に対処する明確な方法はありますか?

私の現在のアプローチ

私は現在、.csvに変換し、それぞれの行を解析しています。私は空白のセルの周りに各行を分割し、行の最初の部分を処理します(一番左のテーブルに属するはずです)。行の残りの部分はキューに入れられ、後で同じ方法で処理されます。私はこのfirst_partを読んで、ヘッダー行かどうかを確認します。そうであれば、それを使って私が扱っているテーブルを特定します(これはグローバルcurrent_dfに格納されています)。ヘッダー行ではない後続の行がこのテーブルに入力されます(ここでは私のテーブルにpandas.DataFrameを使用しています)。

コードは、これまでのところ、以下の(ほとんどが不完全でテストされていないが、それは上記のアプローチを伝える必要があります)です。

class DFManager(object): # keeps track of current table and its headers 
    current_df = None 
    current_headers = [] 

    def set_current_df(self, df, headers): 
     self.current_headers = headers 
     self.current_df = df 


def split_row(row, separator): 
    while row and row[0] == separator: 
     row.pop(0) 
    while row and row[-1] == separator: 
     row.pop() 

    if separator in row: 
     split_index = row.index(separator) 
     return row[:split_index], row[split_index:] 
    else: 
     return row, [] 


def process_df_row(row, dfmgr): 
    df = df_with_header(row) # returns the dataframe with these headers 

    if df is None: # is not a header row, add it to current df 
     df = dfmgr.current_df 
     add_row_to_df(row, df) 
    else: 
     dfmgr.set_current_df(df, row) 


# this is passed the Excel sheet 
def populate_dataframes(xl_sheet): 
    dfmgr = DFManager() 
    row_queue = Queue() 
    for row in xl_sheet: 
     row_queue.put(row) 

    for row in iter(row_queue.get, None): 
     if not row: 
      continue 

     first_part, remainder = split_row(row) 
     row_queue.put(remainder) 

     process_df_row(first_part, dfmgr) 
+0

'header1' *は常にA1にありますか?パターンが異なる(たとえば、常にC1など)か、パターンがまったくありませんか?ヘッダーチェックプロセスをより効率的にするための注目すべきパターンがあるかどうかは不思議です。 – spicypumpkin

+0

ヘッダーは常にB2にあるようです。私はむしろこれに常に頼っていませんが、これは私が見たすべてのExcelファイルに当てはまると思われます –

+0

私はデータフレームへのテーブルの抽出を扱ういくつかのスクリプトを作成しました。すぐにgitリポジトリへのリンクを投稿します。 –

答えて

0

これはでこれを行うには、「クリーン」な方法がありそうでないような特定の状況であります既製のモジュール。

これを行う1つの方法は、既に解決策(Python Pandas - Read csv file containing multiple tables)のように、各テーブルの開始インデックスを見つける必要があるヘッダー情報を使用するかもしれません。

各テーブルの開始位置が決まったら、幅(先験的にわかっているか、または次の空白の列まで読むことによって検出された)を決定し、それらの列をデータフレームに読み込み、 。

キューベースの方法ではなくインデックスベースの方法の利点は、区切り記号が各行にある場所を再発見する必要はなく、どの行断片がどのテーブルに属しているかを把握する必要がないことです。また、1行に2つ以上のテーブルが存在することには無関心です。

関連する問題