wellwell3176
@wellwell3176

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

マトリクス表の整然データ化

Q&A

Closed

解決したいこと

初歩的な質問で恐縮なのですが、元のエクセルが図1のようになっており、非常に扱いづらいです。
図2のような整然データにしたいのですが、何かいい関数や方法などはないでしょうか?
※頭文字のアルファベットは外せなくてもいいです。
image.png
         図1 元データ
image.png
       図2 作りたい整然データ

自分で試したこと

・for文を使って、一個ずつ処理
 D3には「Aネズミ」が入っていて、そのインデックスは1/1、項目はは草食&午後・・・という風に拾っていけそうではあったのですが、
 間違いなくもっといい方法があるだろう思い質問させていただきました。

・形状的にピボットテーブルに近かったので、pd.meltでの逆変換
 ⇨ダメでした。形がピボットテーブルっぽいだけで、ピボットテーブルではない。

・meshgrid関数を使う(https://spcx8.hatenablog.com/entry/2018/09/16/222941)
 ⇨動かない。データフレーム型に適用できないと出ました。

meshグリッドでエラーの起きたときのプログラム
  wb=pd.read_excel("/Book1.xlsx")

  rows,cols = wb.meshgrid(range(mat.shape[0]),range(mat.shape[1]),indexing='ij')
  df = pd.DataFrame()
  df['row'] = rows.flatten()
  df['col'] = cols.flatten()
  df['val'] = mat.flatten()

追加項目

@nkay様の提案手法
df = pd.read_excel("test.xlsx", header=[0, 1], index_col=[0, 1])
df2=df.stack([0, 1])
df2.to_excel("output.xlsx")

image.png
     図:提案手法の出力結果

0

2Answer

df = pd.read_excel("/Book1.xlsx", header=[0, 1], index_col=[0, 1])
df2 = df.stack([0, 1]).str.extractall(r"([A-Z])?(.+)").reset_index(-1, True)

df2.reset_index().to_excel('...')

print(df2)
0 1
1/1 肉食 午前 B ウサギ
1/1 肉食 午後 nan タツ
1/1 草食 午後 A ネズミ
1/2 肉食 午後 B ウサギ
1/2 草食 午前 A ウシ
1/2 草食 午後 B トラ
1/3 肉食 午前 C ヘビ
1/3 肉食 午後 nan タツ
1/3 草食 午前 nan ネズミ
1/3 草食 午後 C ウシ

いかがでしょうか。

2Like

Comments

  1. @wellwell3176

    Questioner

    @nkay様 求めていたのは正にこれです。
    本当にありがとうございます。stack関数は今から勉強します。
    ただ、私の環境で同じことを実行すると、曜日・日付・肉草あたりが全部結合されて表示されます(記事内末尾に画像付記しました)。
    これは環境の差が原因なのでしょうか?

  2. 解答を更新しました。
    セルの結合をさせないためには、`.reset_index()`でインデックスを解除するか、`read_excel()`の引数に`merge_cells=False`を指定してください。
  3. @wellwell3176

    Questioner

    できました! どうもありがとうございます!
    本件質問CLOSEとさせていただきます。

Comments

  1. @wellwell3176

    Questioner

    すみません、よく分かりませんでした。
    A1とB1を削除した後、整然データにバラすのはどうすれば実現できるものなのでしょうか?やはりmelt関数なのでしょうか?

Your answer might help someone💌