LoginSignup
40
38

More than 5 years have passed since last update.

pandas で 3 次元のデータ構造を扱う

Last updated at Posted at 2014-08-21

3 次元のデータを扱う

pandas におけるデータ構造として主要なものに 1 次元つまり線の Series と 2 次元つまり表形式の DataFrame があります。これは pandas における主要なオブジェクトであり Python for Data Analysis でも詳しく解説されています。

しかし実はもう一つ主要なオブジェクトがあります。それが Intro to Data Structures でも 3 つ目に登場する 3 次元の Panel です。

この 3 次元のデータ構造は、たとえば毎日の表データから任意の数値を取り出して時系列のログに関する統計分析をおこないたいといった用途において役立ちます。

Panel オブジェクトを作る

Panel は辞書形式にした DataFrame または 3 次元の ndarray を引数にとることで生成することができます。具体的にやってみましょう。

import pandas as pd
rng = pd.date_range('1/1/2014',periods=100,freq='D')

# 乱数でデータフレームを作っていく、インデックスは ABCD とする
df1 = pd.DataFrame(np.random.randn(100, 4), index = rng, columns = ['A','B','C','D'])
df2 = pd.DataFrame(np.random.randn(100, 4), index = rng, columns = ['A','B','C','D'])
df3 = pd.DataFrame(np.random.randn(100, 4), index = rng, columns = ['A','B','C','D'])

# これらデータフレームをまとめて Panel オブジェクトをつくる
pf = pd.Panel({'df1':df1,'df2':df2,'df3':df3})

pf
#=>
# <class 'pandas.core.panel.Panel'>
# Dimensions: 3 (items) x 100 (major_axis) x 4 (minor_axis)
# Items axis: df1 to df3
# Major_axis axis: 2014-01-01 00:00:00 to 2014-04-10 00:00:00
# Minor_axis axis: A to D

このように Panel オブジェクトが生成されました。
それぞれの次元は Items axis, Major_axis, Minor_axis と言います。

このオブジェクトにどのようなメソッドがあるかはドキュメントを参照すると良いでしょう。

Panel オブジェクトの主要な操作

まずはインデックスでアクセスするのがポピュラーでしょう。

pf.ix[0] # df1 へのアクセス
pf.ix[1] # df2 へのアクセス
pf['df1'] # これも df1 へのアクセス

このように Panel が持つ各表へアクセスすることができます。

# 表へ新しいカラムを追加
pf['df1']['E'] = pd.DataFrame(np.random.randn(100, 1), index = rng)
pf['df2']['E'] = pd.DataFrame(np.random.randn(100, 1), index = rng)

# データ構造を確認する
pf.shape
#=> (3, 100, 4)

# df1 表の E 列のカラムを 10 件アクセスする
pf.ix['df1',-10:,'E']
#=>
# 2014-04-01   -1.623615
# 2014-04-02    1.878481
# 2014-04-03   -0.890555
# 2014-04-04    0.736037
# 2014-04-05   -1.451665
# 2014-04-06    0.126473
# 2014-04-07    0.997485
# 2014-04-08   -1.252981
# 2014-04-09   -1.136791
# 2014-04-10   -1.873199

また Panel は to_flame() で積み重ねたデータフレームに変換することができます。この積み重ねたデータフレームに対し統計関数を利用することができます。さらにこのオブジェクトは to_panel() で元の Panel に再変換できます。

pf.to_frame().to_panel()
#=>
# <class 'pandas.core.panel.Panel'>
# Dimensions: 3 (items) x 100 (major_axis) x 4 (minor_axis)
# Items axis: df1 to df3
# Major_axis axis: 2014-01-01 00:00:00 to 2014-04-10 00:00:00
# Minor_axis axis: A to D

ログデータの分析に Panel を使う

あるディレクトリにアプリケーションのログファイルが毎日たとえば Fluentd などで生成されているとします。このログファイルを日付をまたいで分析する場合、一日分のデータを表にして 3 次元のデータ構造とすれば時系列の分析ができますから大変便利です。

先日の記事でサンプルとしてちらっと出てきたディレクトリのファイル一覧を取得するプログラムを少し書き換えて応用します。

import sys
import os
import pandas as pd

def list_files(path):
    dic = {}
    for root, dirs, files in os.walk(path):
        for filename in files:
            fullname = os.path.join(root, filename)
            if filename.startswith("fluent") \
               and filename.endswith(".log"):
                try:
                    print("Reading: %(filename)s" % locals())
                    df = pd.read_table(
                        os.path.join(path, filename), header=None)
                    dic[filename] = df
                except pd.parser.CParserError:
                    print("Skip: %(filename)s" % locals())
    return pd.Panel(dic)

このメソッドで戻ってくる Panel オブジェクトは複数のログファイルをまとめた 3 次元のデータ構造ですから、統計関数を利用して時系列のデータ分析などをすることができます。

まとめ

pandas では Panel を利用して 3 次元のデータ構造を扱うことができます。行と列のデータ構造に加え、もう 1 つ次元を加えることで、時系列のデータ分析などにおいて威力を発揮します。

40
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
38