今回はまずMulti-Levelを話ししたいと思います。pandasからはこのような説明があります:
Hierarchical / Multi-level indexing is very exciting as it opens the door to some quite sophisticated data analysis and manipulation, especially for working with higher dimensional data. In essence, it enables you to store and manipulate data with an arbitrary number of dimensions in lower dimensional data structures like Series (1d) and DataFrame (2d).
Mult-indexを作る
下記のコードはTupleを作ります。
import numpy as np
import pandas as pd
outside=['G1','G1','G1','G2','G2','G2']
inside=[1,2,3,1,2,3]
#[('G1', 1), ('G1', 2), ('G1', 3), ('G2', 1), ('G2', 2), ('G2', 3)]
hier_index=list(zip(outside,inside))
次はpd.MultIndexの使ってMultIndexを作ります。
hier_index=pd.MultiIndex.from_tuples(hier_index) hier_index
出力はこうになります:
今度はDataFrameの中に入れてみます;
df=pd.DataFrame(np.random.randn(6,2),hier_index,['A','B'])
これは実際jupyterで出力されたTableです。
| A | B | ||
|---|---|---|---|
| G1 | 1 | -0.268808 | 1.027353 |
| 2 | -1.416180 | -1.408194 | |
| 3 | 0.355412 | 2.048836 | |
| G2 | 1 | 0.307890 | -0.533687 |
| 2 | 0.871801 | 0.513956 | |
| 3 | 0.508417 | 0.119123 |
Mult-indexの中にあるElementsを選択
Columns ‘G1’を選択します。
df.loc['G1']
これは実際jupyterで出力されたTableです。G1だけ戻りました。
| A | B | |
|---|---|---|
| 1 | -0.268808 | 1.027353 |
| 2 | -1.416180 | -1.408194 |
| 3 | 0.355412 | 2.048836 |
Columns ‘G1’のRow1を選択します。
df.loc['G1'].loc[1]
Seriesが戻りました。
A -0.268808 B 1.027353 Name: 1, dtype: float64
Row’A’を選択します。
df['A']
Seriesが戻りました。やり方は普通のDataFrame操作と同じです。
G1 1 -0.268808
2 -1.416180
3 0.355412
G2 1 0.307890
2 0.871801
3 0.508417
Name: A, dtype: float64
Columns ‘G1’のRow1の”B”を選択します。
df.loc['G1'].loc[1]['B']
値が戻りました。
1.027352545488271
df.index.names?
https://pandas.pydata.org/pandas-docs/stable/advanced.html によりますと:
All of the MultiIndex constructors accept a names argument which stores string names for the levels themselves. If no names are provided, None will be assigned:
つまり全てのMultIndex構造体がnamesの文字列パラメータを受けることができ、このnamesはなにか保存かというとMultIndexのLevel自体です。もしnamesがなにも渡ってなかったら、Noneになります。
df.index.names
いまはまだなにも渡してないからNoneになります:
FrozenList([None, None])
今度はnamesを文字列渡してみます。
df.index.names=['Groups','Name']
df.index.namesはこうになります。
FrozenList(['Groups', 'Name'])
dfはこうになります:
| A | B | ||
|---|---|---|---|
| Groups | Name | ||
| G1 | 1 | -0.268808 | 1.027353 |
| 2 | -1.416180 | -1.408194 | |
| 3 | 0.355412 | 2.048836 | |
| G2 | 1 | 0.307890 | -0.533687 |
| 2 | 0.871801 | 0.513956 | |
| 3 | 0.508417 | 0.119123 |
df.xs?
The xs method of DataFrame additionally takes a level argument to make selecting data at a particular level of a MultiIndex easier.
G1のすべてを選択します。
df.xs('G1')
これは実際jupyterで出力されたTableです。G1だけ戻りました。df.locと同じですね〜
| A | B | |
|---|---|---|
| Name | ||
| 1 | -0.268808 | 1.027353 |
| 2 | -1.416180 | -1.408194 |
| 3 | 0.355412 | 2.048836 |
G1の中にLevel=Nameでなおかつ値=1のRowsを選択します。
df.xs(1,level='Name')
これは実際jupyterで出力されたTableです。G1とG1の中にName=1だけのRows戻りました。
| A | B | |
|---|---|---|
| Groups | ||
| G1 | -0.268808 | 1.027353 |
| G2 | 0.307890 | -0.533687 |
今度はGroupsの中に”G1″だけを選択します。
df.xs('G1',level='Groups')
これは実際jupyterで出力されたTableです。Group=’G1’だけのRows戻りました。
| A | B | |
|---|---|---|
| Name | ||
| 1 | -0.268808 | 1.027353 |
| 2 | -1.416180 | -1.408194 |
| 3 | 0.355412 | 2.048836 |
それじゃねー