Help us understand the problem. What is going on with this article?

スペースでインデントされた文字列をDataFrameとDictionaryに変換

開発環境

Windows 10
Python 3.7.3
※ pandasモジュール使用

開発/投稿の動機

コマンドの出力結果をパースして分析するために開発、メモを兼ねて投稿

変換対象文字列

sample_output.py
output = '''aaa
bbb
    ccc
    ddd
        eee
        fff
            gggg
        hhh
            iii
                jjj'''

データ構造に関する変数を定義

setting.py
# インデント単位を定義
indent_num = 4
# 階層数を定義
max_depth = int(max([i.count(' ') for i in output_list]) / indent_num)

StringからDataFrameへ加工

str_to_df.py
import pandas as pd

output_df = pd.DataFrame(index=[],columns=range(max_depth + 1))
for i in range(len(output_list)):
    if output_list[i].count(' ') == 0:
        # 最深までの足りない要素をNone埋めして挿入
        temp_row = [output_list[i]]
        temp_row.extend([None] * (max_depth)) # max_depth - すでに挿入した要素数(1) + depthが0から始まるため1を足す をプラスマイマスゼロのため省略
        output_df = output_df.append(pd.Series(temp_row, index=output_df.columns), ignore_index=True)
        outer_row = [output_list[i]]
        depth = 0
    else:
        # 1つ前のレコードよりも1階層深かったら"depth"を進める
        if output_list[i].count(' ') == (depth + 1) * indent_num:
            depth += 1
        # 挿入用のリストを作成
        temp_row = outer_row.copy()
        temp_row.append(output_list[i].strip(' '))
        list_length = len(temp_row)
        # 最深よりも浅いレコードはNone埋めして挿入
        if list_length < max_depth + 1:
            temp_row.extend([None] * (max_depth - list_length + 1))
            output_df = output_df.append(pd.Series(temp_row, index=output_df.columns), ignore_index=True)
        # 最深のレコードはそのまま挿入
        else:
            output_df = output_df.append(pd.Series(temp_row, index=output_df.columns), ignore_index=True)
        # 次のレコードが1階層深かったらouter_rowを挿入したレコード(Noneは除去)と置き換える
        if i + 1 < len(output_list):
            if output_list[i + 1].count(' ') == (depth + 1) * indent_num:
                outer_row = [x for x in temp_row if x]

DataFrameからDictionaryへ加工

df_to_dict.py
output_dict = {}
for i in sorted(output_df.keys())[:-1]:
    for j in [x for x in output_df[i].drop_duplicates() if x]:   
        if i == 0:
            # 配下の要素が無かったら外側の辞書定義のみ
            if len([x for x in output_df[output_df[i] == j][i + 1] if x]) == 0:
                output_dict[j] = None
            else:
                output_dict[j] = {}
                filtered_dict = output_dict[j]
        else:
            # 配下の要素が無かったら自分だけ追加
            if len([x for x in output_df[output_df[i] == j][i + 1] if x]) == 0:
                if (j not in filtered_dict) & (i != max_depth - 1):
                    filtered_dict[j] = None
            # 配下の要素があったら辞書を作って埋める
            elif i != max_depth - 1:
                filtered_dict[j] = {}
                temp_dict = {}
                # 配下のキーをループ処理
                for key in [x for x in output_df[output_df[i] == j][i + 1].drop_duplicates() if x]:
                    # すでにキーがあったら更新
                    if key in temp_dict.keys():
                        temp_dict.update({key:[x for x in list(output_df[output_df[max_depth - 1] == key][max_depth]) if x]})
                    # 無かったら追加
                    else:
                        temp_dict[key] = [x for x in list(output_df[output_df[max_depth - 1] == key][max_depth]) if x]
                # 作成した辞書を挿入
                filtered_dict[j] = temp_dict
あとがき

求める出力を得られるようになったため当面このまま使うが、不要なロジックの精査を要する。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away