私はデータベースに解析し、書き込むことを試みているひどくレイアウトされたExcelシートを扱っています。多くのテーブルを持つExcelシートからデータフレームを解析する方法(Python、おそらくPandasを使用)
すべてのシートは複数のテーブルを持つことができます。これらの可能なテーブルのヘッダーはわかっていますが、特定のシート上にあるテーブルはそうではありませんし、シート上の正確な位置も同じではありません(テーブルは一貫した方法で整列しません)。これを説明するために2つのシートレイアウトを追加しました。This layoutには2つのテーブルがあり、this oneには最初のテーブルがありますが、同じ場所にはありません。私が知っている何
:
- すべての可能なテーブルのヘッダは、その個々のテーブルには、
- テーブルが空白のセルで区切られ、そのヘッダで識別することができます。彼らはお互いに触れません。
私の質問パンダのような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)
'header1' *は常にA1にありますか?パターンが異なる(たとえば、常にC1など)か、パターンがまったくありませんか?ヘッダーチェックプロセスをより効率的にするための注目すべきパターンがあるかどうかは不思議です。 – spicypumpkin
ヘッダーは常にB2にあるようです。私はむしろこれに常に頼っていませんが、これは私が見たすべてのExcelファイルに当てはまると思われます –
私はデータフレームへのテーブルの抽出を扱ういくつかのスクリプトを作成しました。すぐにgitリポジトリへのリンクを投稿します。 –