いろいろ倉庫

KNIME、EXCEL、R、Pythonなどの備忘録

【Python】表を縦長にしたい

・お題:マトリックスになっている表を、リスト形式に変形したい。

 

・表の形式として、マトリックス形式とリスト形式というやつがあるらしい。

マトリックス形式が以下の形式で、プレートマップのような感じ。

対して、それぞれの要素を縦に並べたような表を、リスト形式と呼ぶっぽい(下図)。

マトリックス形式の方が視覚的に情報を把握しやすい反面、自由度が低く、無駄が多い場合がある。リスト形式の方がデータを取り扱う場合には便利なことが多い。ということで、表を縦長に成型する方法を調べた。

・プレートマップを意識し、以下のデータの入ったcsvファイルをマトリックス形式で読み込む。

  1 2 3 4 5 6
A 2.3 7.1 8.1 6.9 3.3 8.1
B 7.3 3.5 4.4 4.6 7.4 6.5
C 5.4 9.4 1.6 6.6 0.4 7.1
D 9.9 2.9 2.9 2.9 1.5 7.3

import numpy as np
import pandas as pd

df=pd.read_csv("xxx.csv",index_col=0)

とすると、dfの中身は以下になる。

・これを縦長にするには、stack()を使う。

df2=df.stack()

とすると、df2の中身は、以下になる。

なんだか気持ち悪いと思ったら、df2と名付けたにもかかわらず、Series形式で、しかもマルチインデックスが返ってきた。

・マルチインデックスを解除するには、.reset_index()すれば良い。

df3=df2.reset_index()

とすれば、df3の中身は、

となる。これで目的は達した。

・せっかくなので、縦長の表をマトリックスに戻す。手順を逆に辿れば良いので、まずはマルチインデックスにする。

df4=df3.set_index(["level_0","level_1"])

これでdf4は

になる。

・これを単純にunstackすると、マルチカラムが鬱陶しいことになる(下図)。

df4.unstack()

droplevelでデータのカラム名(0)を除去すると、ちょっとマシになる。

df4.unstack().droplevel([0],axis=1)

一度振られたlevel_0の消し方はよく分からなかった。

・次に、複数の条件から定義される投与群×投与日という形のマルチインデックスの表(下表)を縦長にする。

Compound Dose Day0 Day1 Day2
A 1 25.9 25.9 26.1
A 3 25.4 25.4 26.3
B 1 25.7 25.5 25.5
B 3 25.7 25.5 25.1

・といっても、読み込みの際にマルチインデックスを設定すれば良いだけみたい。

df=pd.read_csv("xxxx.csv",index_col=[0,1])

dfの中身

df2=df.stack().reset_index()

df2の中身

・ちなみに、マルチインデックスに戻してunstackしてdroplevelすると、元のマトリックスぽくなる。

df3=df2.set_index(["Compound","Dose","level_2"]).unstack().droplevel([0],axis=1)

df3の中身

 

・なんだか腑に落ちないけれど、一応それっぽい形にはなった。

 

おわり。