StatsFragments

Python, R, Rust, 統計, 機械学習とか

Python xray で 多次元データを pandas ライクに扱う

はじめに

pandas では 2 次元、表形式のデータ ( DataFrame ) を主な対象としているが、ときには 3 次元以上のデータを扱いたい場合がある。そういった場合 以下のような方法がある。

自分は MultiIndex を使うことが多いが、データを 2 次元にマップしなければならないため 種類によっては直感的に扱いにくい。PanelPanelNDDataFrame と比べると開発が活発でなく、特に Panel4DPanelND は 現時点で Experimental 扱いである。また、今後の扱いをどうするかも議論がある。numpy.ndarray では データのラベル付けができない。

xray とは

ラベル付きの多次元データを多次元のまま 直感的に扱えるパッケージとして xray がある。作者は pandas 開発チーム仲間の shoyer だ。そのため、APIpandas にかなり近いものになっている。

xray は大きく以下ふたつのデータ構造を持つ。これらを使うと多次元データをより直感的に操作することができる。

  • xray.DataArray: numpy の多次元配列にラベルでのアクセスを追加したもの。データは任意の次元を持つことができる。
  • xray.Dataset: 複数xray.DataArray をまとめるセット。

インストール

pip で。

$ pip install xray

データの準備

まず、必要なパッケージをインポートする。

import numpy as np
import pandas as pd

pd.__version__
# '0.16.2'

import xray
xray.__version__
# '0.5.2'

サンプルデータとして、気象庁から 2015年7月20日〜25日の東京、八王子、大島の最高気温のデータを使いたい。以下のサイトからダウンロードした。データは 日付、場所 2 次元の配列となる。

f:id:sinhrks:20150726225910p:plain

data2 = np.array([[34.2, 30.2, 33.5],
                  [36.0, 29.3, 34.9],
                  [35.3, 29.7, 32.8],
                  [30.1, 27.6, 30.4],
                  [33.6, 30.1, 33.9],
                  [34.1, 28.0, 33.1]])

この numpy.ndarray から xray.DataArray インスタンスを作成する。データへアクセスするためのラベル ( pandas でいう index のようなもの ) は coords キーワードで指定する。また、dims キーワードを使って各次元それぞれにも名前をつけることができる。ここでは 以下のような DataArray を作成している。

  • データは 2 つの次元 date, location を持つ。
  • date 次元は dates で指定される 6 つの日付のラベルを持つ。
  • location 次元は locs で指定される 3 つの場所のラベルを持つ。

2 次元のため、pandas.DataFrame でいうと dateindexに、 locationcolumns に対応しているイメージ。

locs = [u'八王子', u'大島', u'東京']
dates = pd.date_range('2015-07-20', periods=6, freq='D')
da2 = xray.DataArray(data2, coords=[dates, locs], dims=['date', 'location'])
da2
# <xray.DataArray (date: 6, location: 3)>
# array([[ 34.2,  30.2,  33.5],
#        [ 36. ,  29.3,  34.9],
#        [ 35.3,  29.7,  32.8],
#        [ 30.1,  27.6,  30.4],
#        [ 33.6,  30.1,  33.9],
#        [ 34.1,  28. ,  33.1]])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...

# 各次元の名前
da2.dims
# ('date', 'location')

# 各次元の詳細
da2.coords
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...

# date 次元のラベル
da2.coords['date']
# <xray.DataArray 'date' (date: 6)>
# array(['2015-07-20T09:00:00.000000000+0900',
#        '2015-07-21T09:00:00.000000000+0900',
#        '2015-07-22T09:00:00.000000000+0900',
#        '2015-07-23T09:00:00.000000000+0900',
#        '2015-07-24T09:00:00.000000000+0900',
#        '2015-07-25T09:00:00.000000000+0900'], dtype='datetime64[ns]')
# Coordinates:
#   * date     (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...

データの選択

xray でのデータ選択は pandas と類似の方法で行える。pandas でのデータ選択についてはこちらを。

ある次元から、特定のラベルをもつデータを選択したい場合、pandas と同じく .loc が使える。

# 7/25 のデータを選択
da2.loc[pd.Timestamp('2015-07-25')]
# <xray.DataArray (location: 3)>
# array([ 34.1,  28. ,  33.1])
# Coordinates:
#     date      datetime64[ns] 2015-07-25
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...

また、対象の次元が datetime64 型の場合は、pandas と同じく日時文字列でも指定が可能 (部分文字列によるスライシング、詳細以下)。

# 7/25 のデータを選択
da2.loc['2015-07-25']
# <xray.DataArray (location: 3)>
# array([ 34.1,  28. ,  33.1])
# Coordinates:
#     date      datetime64[ns] 2015-07-25
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...

また、ラベルではなく位置 ( n番目など ) によって選択する場合は __getitem__ を使う。pandas では .iloc に対応。

# 末尾 = 最新の日付のデータを取得
da2[-1]
# <xray.DataArray (location: 3)>
# array([ 34.1,  28. ,  33.1])
# Coordinates:
#     date      datetime64[ns] 2015-07-25
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...

2 次元目以降をラベル / 位置によって指定する場合は、引数をカンマで区切り、選択に利用する次元の位置に対応する値を渡す。

# date は全選択、location が東京のデータを選択
da2.loc[:, u'東京']
# <xray.DataArray (date: 6)>
# array([ 33.5,  34.9,  32.8,  30.4,  33.9,  33.1])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     location  <U3 u'\u6771\u4eac'

# date は全選択、location が 3 番目 = 東京のデータを選択
da2[:, 2]
# <xray.DataArray (date: 6)>
# array([ 33.5,  34.9,  32.8,  30.4,  33.9,  33.1])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     location  <U3 u'\u6771\u4eac'

データ選択に利用する次元自体もラベルで指定したい場合は .sel を使う。.sel では次元の順序に関係なく値を指定できるため、高次元になった場合もシンプルだ。

# 東京のデータを選択
da2.sel(location=u'東京')
# <xray.DataArray (date: 6)>
# array([ 33.5,  34.9,  32.8,  30.4,  33.9,  33.1])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     location  <U3 u'\u6771\u4eac'

# 7/22, 7/23 の 東京のデータを選択
da2.sel(location=u'東京', date=pd.DatetimeIndex(['2015-07-22', '2015-07-23']))
# <xray.DataArray (date: 2)>
# array([ 32.8,  30.4])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-22 2015-07-23
#     location  <U3 u'\u6771\u4eac'

もしくは .loc, __getitem__ に以下のような辞書を渡してもよい。

# 東京のデータを選択
da2.loc[dict(location=u'東京')]
# <xray.DataArray (date: 6)>
# array([ 33.5,  34.9,  32.8,  30.4,  33.9,  33.1])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     location  <U3 u'\u6771\u4eac'

公式ドキュメント では、xray.DataArray からのデータ選択を以下のような表で整理している。

次元の指定 値の指定 DataArrayメソッド
位置 位置 da2[:, 0]
位置 ラベル da2.loc[:, u'東京']
ラベル 位置 da2.isel(location=0), da2[dict(space=0)]
ラベル ラベル da2.sel(location=u'東京'), da2.loc[dict(location=u'東京')]

次元の追加

ここまでは 2 次元のデータを使っていたが、最低気温と平均気温のデータを追加して 3 次元のデータとする。

# 最低気温
data3 = np.array([[24.7, 25.1, 25.8],
                  [23.4, 24.3, 25.4],
                  [22.7, 23.8, 25.4],
                  [24.5, 24.4, 24.7],
                  [24.9, 24.6, 25.0],
                  [23.7, 24.8, 24.8]])
# 平均気温
data4 = np.array([[27.8, 26.5, 28.8],
                  [29.7, 26.3, 29.4],
                  [29.5, 26.5, 28.9],
                  [26.9, 25.3, 27.0],
                  [27.7, 26.4, 28.1],
                  [29.0, 26.1, 28.6]])
data = np.dstack([data2, data3, data4])

# 日時、場所、データの種類 の 3 次元
data.shape
# (6, 3, 3)

da3 = xray.DataArray(data, coords=[dates, locs, [u'最高', u'最低', u'平均']],
                     dims=['date', 'location', 'type'])
da3
# <xray.DataArray (date: 6, location: 3, type: 3)>
# array([[[ 34.2,  24.7,  27.8],
#         [ 30.2,  25.1,  26.5],
#         [ 33.5,  25.8,  28.8]],
# 
#      ... 
# 
#        [[ 34.1,  23.7,  29. ],
#         [ 28. ,  24.8,  26.1],
#         [ 33.1,  24.8,  28.6]]])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...
#   * type      (type) <U2 u'\u6700\u9ad8' u'\u6700\u4f4e' u'\u5e73\u5747'

3 次元以上の場合もデータ選択のルールは一緒なのでわかりやすい。

# 7/24 のデータを選択
da3.loc['2015-07-24']
# <xray.DataArray (location: 3, type: 3)>
# array([[ 33.6,  24.9,  27.7],
#        [ 30.1,  24.6,  26.4],
#        [ 33.9,  25. ,  28.1]])
# Coordinates:
#     date      datetime64[ns] 2015-07-24
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...
#   * type      (type) <U2 u'\u6700\u9ad8' u'\u6700\u4f4e' u'\u5e73\u5747'

# 7/24 の 最高気温のデータを選択
da3.loc['2015-07-24', :, u'最高']
# <xray.DataArray (location: 3)>
# array([ 33.6,  30.1,  33.9])
# Coordinates:
#     date      datetime64[ns] 2015-07-24
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...
#     type      <U2 u'\u6700\u9ad8'

# 東京 の 最高気温のデータを選択
da3.sel(location=u'東京', type=u'最高')
# <xray.DataArray (date: 6)>
# array([ 33.5,  34.9,  32.8,  30.4,  33.9,  33.1])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     location  <U3 u'\u6771\u4eac'
#     type      <U2 u'\u6700\u9ad8'

算術演算

pandas と同じく、xray.DataArray 同士での算術演算が可能。各日の最高気温と最低気温の差を求めると、

da3.sel(type=u'最高') - da3.sel(type=u'最低') 
# <xray.DataArray (date: 6, location: 3)>
# array([[  9.5,   5.1,   7.7],
#        [ 12.6,   5. ,   9.5],
#        [ 12.6,   5.9,   7.4],
#        [  5.6,   3.2,   5.7],
#        [  8.7,   5.5,   8.9],
#        [ 10.4,   3.2,   8.3]])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...

# 結果から 八王子 のデータだけを選択
(da3.sel(type=u'最高') - da3.sel(type=u'最低')).sel(location=u'八王子')
# <xray.DataArray (date: 6)>
# array([  9.5,  12.6,  12.6,   5.6,   8.7,  10.4])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     location  <U3 u'\u516b\u738b\u5b50'

データのグループ化 / 集約

グループ化 / 集約も pandas とほぼ同じ形式でできる。location によってグループ化し、期間中の最高気温を出してみる。

da3.groupby('location')
# <xray.core.groupby.DataArrayGroupBy at 0x109a56f90>

da3.groupby('location').max()
# <xray.DataArray (location: 3)>
# array([ 36. ,  30.2,  34.9])
# Coordinates:
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...

グループ化した結果は、イテレーションによって順番に処理することもできる。

for name, g in da3.groupby('location'):
    print(name)
    print(g)
# 八王子
# <xray.DataArray (date: 6, type: 3)>
# array([[ 34.2,  24.7,  27.8],
#        [ 36. ,  23.4,  29.7],
#        [ 35.3,  22.7,  29.5],
#        [ 30.1,  24.5,  26.9],
#        [ 33.6,  24.9,  27.7],
#        [ 34.1,  23.7,  29. ]])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * type      (type) <U2 u'\u6700\u9ad8' u'\u6700\u4f4e' u'\u5e73\u5747'
#     location  <U4 u'\u516b\u738b\u5b50'
# 
# 以降略

データの結合 / 連結

上で作成した DataArray に、別のデータを追加したい。適当なデータを探したところ、ある成人男性のお住まいの気温データ を見つけた。これを日別で集計して連結したい。

# GitHub からデータを取得
df = pd.read_csv('https://raw.githubusercontent.com/dichika/mydata/master/room.csv')
df['time'] = pd.to_datetime(df['time'])

# light は光量、temperatur は気温
df.head()
#                  time  light  temperature
# 0 2015-02-12 01:45:04  463.0       26.784
# 1 2015-02-12 02:00:03  473.0       26.630
# 2 2015-02-12 02:15:04  467.9       25.983
# 3 2015-02-12 02:30:04    0.0       25.453
# 4 2015-02-12 02:45:04    0.0       23.650

# 期間中にフィルタ
df = df[df['time'] >= pd.Timestamp('2015-07-20')]
# 日時でグループ化 / 集約
agg = df.groupby(pd.Grouper(key='time', freq='D'))['temperature'].agg(['max', 'min', 'mean'])
agg
#                max     min       mean
# time                                 
# 2015-07-20  28.374  26.450  27.484604
# 2015-07-21  33.790  26.800  30.132792
# 2015-07-22  34.180  27.070  30.134375
# 2015-07-23  28.779  27.412  28.290918

xray でデータを連結するためには、連結する次元 (ここでは location) 以外のデータの要素数を一致させる必要がある。上記のデータは数日遅れで公開されているため、直近を NaN でパディングして xray.DataArray を作成する。

agg.loc[pd.Timestamp('2015-07-24'), :] = np.nan
agg.loc[pd.Timestamp('2015-07-25'), :] = np.nan
agg
#                max     min       mean
# time                                 
# 2015-07-20  28.374  26.450  27.484604
# 2015-07-21  33.790  26.800  30.132792
# 2015-07-22  34.180  27.070  30.134375
# 2015-07-23  28.779  27.412  28.290918
# 2015-07-24     NaN     NaN        NaN
# 2015-07-25     NaN     NaN        NaN

d = xray.DataArray(agg.values.reshape(6, 1, 3), coords=[agg.index, [u'誰かの家'], [u'最高', u'最低', u'平均']],
                   dims=['date', 'location', 'type'])
d
# <xray.DataArray (date: 6, location: 1, type: 3)>
# array([[[ 28.374     ,  26.45      ,  27.48460417]],
#        [[ 33.79      ,  26.8       ,  30.13279167]],
#        [[ 34.18      ,  27.07      ,  30.134375  ]],
#        [[ 28.779     ,  27.412     ,  28.29091765]],
#        [[         nan,          nan,          nan]],
#        [[         nan,          nan,          nan]]])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * location  (location) <U4 u'\u8ab0\u304b\u306e\u5bb6'
#   * type      (type) <U2 u'\u6700\u9ad8' u'\u6700\u4f4e' u'\u5e73\u5747'

データの連結は xray.concat で可能。新しい場所のデータを追加 (連結) したいので、対象の次元として location を指定する。

da3 = xray.concat([da3, d], dim='location')
da3.sel(location=u'誰かの家')
# <xray.DataArray (date: 6, type: 3)>
# array([[ 28.374     ,  26.45      ,  27.48460417],
#        [ 33.79      ,  26.8       ,  30.13279167],
#        [ 34.18      ,  27.07      ,  30.134375  ],
#        [ 28.779     ,  27.412     ,  28.29091765],
#        [         nan,          nan,          nan],
#        [         nan,          nan,          nan]])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * type      (type) <U2 u'\u6700\u9ad8' u'\u6700\u4f4e' u'\u5e73\u5747'
#     location  <U4 u'\u8ab0\u304b\u306e\u5bb6'

ほか、merge で結合もできる。

Dataset の利用

xray では、DataArray クラスを複数まとめて Dataset クラスとして扱うことができる。元となる DataArray は同じ次元でなくてもよい。

Dataset を作成するため、降水量、湿度 それぞれ 2 次元の DataArray を用意する。

# 降水量
precip = np.array([[0, np.nan, 0],
                   [0, np.nan, np.nan],
                   [0, 0, np.nan],
                   [6.5, 1, 4.5],
                   [30.0, 0, 7.0],
                   [0, np.nan, np.nan]])
precip = xray.DataArray(precip, coords=[dates, locs], dims=['date', 'location'])
precip
# <xray.DataArray (date: 6, location: 3)>
# array([[  0. ,   nan,   0. ],
#        [  0. ,   nan,   nan],
#        [  0. ,   0. ,   nan],
#        [  6.5,   1. ,   4.5],
#        [ 30. ,   0. ,   7. ],
#        [  0. ,   nan,   nan]])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...

# 湿度
humid = np.array([[np.nan, 88, 75],
                  [np.nan, 85, 65],
                  [np.nan, 87, 61],
                  [np.nan, 91, 80],
                  [np.nan, 86, 83],
                  [np.nan, 88, 80]])
humid = xray.DataArray(humid, coords=[dates, locs], dims=['date', 'location'])
humid
# <xray.DataArray (date: 6, location: 3)>
# array([[ nan,  88.,  75.],
#        [ nan,  85.,  65.],
#        [ nan,  87.,  61.],
#        [ nan,  91.,  80.],
#        [ nan,  86.,  83.],
#        [ nan,  88.,  80.]])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * location  (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...

これらと気温データをあわせて xray.Dataset を作成する。Dataset が持つ次元は Dimenstions, Coordinates に表示される。 Dataset に含まれる DataArrayData variables 中に表示され、それぞれどの次元を含んでいるかがわかる。元データと同じく、気温は 3 次元、ほかは 2 次元のデータとなっている。

ds = xray.Dataset({'temperature': da3,
                   'precipitation': precip,
                   'humidity': humid})
ds
# <xray.Dataset>
# Dimensions:        (date: 6, location: 4, type: 3)
# Coordinates:
#   * date           (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#   * location       (location) object u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...
#   * type           (type) <U2 u'\u6700\u9ad8' u'\u6700\u4f4e' u'\u5e73\u5747'
# Data variables:
#     precipitation  (date, location) float64 0.0 nan 0.0 nan 0.0 nan nan nan ...
#     temperature    (date, location, type) float64 34.2 24.7 27.8 30.2 25.1 ...
#     humidity       (date, location) float64 nan 88.0 75.0 nan nan 85.0 65.0 ...

ds.data_vars
# Data variables:
#     precipitation  (date, location) float64 0.0 nan 0.0 nan 0.0 nan nan nan ...
#     temperature    (date, location, type) float64 34.2 24.7 27.8 30.2 25.1 ...
#     humidity       (date, location) float64 nan 88.0 75.0 nan nan 85.0 65.0 ...

Dataset からのデータ選択は、Dataset に含まれるすべての DataArray に対して行われる。DataArray とは異なり、次元は必ずラベルで指定する必要がある。

次元の指定 値の指定 Datasetメソッド
位置 位置 なし
位置 ラベル なし
ラベル 位置 ds.isel(location=2), ds[dict(location=2)]
ラベル ラベル ds.sel(location=u'東京'), ds.loc[dict(location=u'東京')]
# 東京 のデータを選択
ds.sel(location=u'東京')
# <xray.Dataset>
# Dimensions:        (date: 6, type: 3)
# Coordinates:
#   * date           (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     location       object u'\u6771\u4eac'
#   * type           (type) <U2 u'\u6700\u9ad8' u'\u6700\u4f4e' u'\u5e73\u5747'
# Data variables:
#     precipitation  (date) float64 0.0 nan nan 4.5 7.0 nan
#     temperature    (date, type) float64 33.5 25.8 28.8 34.9 25.4 29.4 32.8 ...
#     humidity       (date) float64 75.0 65.0 61.0 80.0 83.0 80.0

# 東京 の 平均気温 を選択
ds.sel(location=u'東京', type=u'平均')['temperature']
# <xray.DataArray 'temperature' (date: 6)>
# array([ 28.8,  29.4,  28.9,  27. ,  28.1,  28.6])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     type      <U2 u'\u5e73\u5747'
#     location  object u'\u6771\u4eac'

# 東京 の 湿度 を選択
ds.sel(location=u'東京')['humidity']
# <xray.DataArray 'humidity' (date: 6)>
# array([ 75.,  65.,  61.,  80.,  83.,  80.])
# Coordinates:
#   * date      (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     location  object u'\u6771\u4eac'

# 対応する DataArray がない場合は NaN となる
ds.sel(location=u'誰かの家')
# <xray.Dataset>
# Dimensions:        (date: 6, type: 3)
# Coordinates:
#   * date           (date) datetime64[ns] 2015-07-20 2015-07-21 2015-07-22 ...
#     location       object u'\u8ab0\u304b\u306e\u5bb6'
#   * type           (type) <U2 u'\u6700\u9ad8' u'\u6700\u4f4e' u'\u5e73\u5747'
# Data variables:
#     precipitation  (date) float64 nan nan nan nan nan nan
#     temperature    (date, type) float64 28.37 26.45 27.48 33.79 26.8 30.13 ...
#     humidity       (date) float64 nan nan nan nan nan nan

そのほかの操作も DataArray と同じようにできる。

# location ごとに期間中の最大値を計算
ds.groupby('location').max()
# <xray.Dataset>
# Dimensions:        (location: 3)
# Coordinates:
#   * location       (location) <U3 u'\u516b\u738b\u5b50' u'\u5927\u5cf6' ...
# Data variables:
#     precipitation  (location) float64 30.0 1.0 7.0
#     temperature    (location) float64 36.0 30.2 34.9
#     humidity       (location) float64 nan 91.0 83.0

pandas のデータ形式への変換

DataArray, Dataset はそれぞれ pandas のデータに変換できる。元データが 3 次元以上の場合、変換後の pandas のデータは MultiIndex を持つことになる。

また、上の例では 次元が異なる DataArray から Dataset を作成した。このとき、存在しない次元 ( ここでは type ) のデータはすべて同じ値でパディングされる。

ds.to_dataframe()

f:id:sinhrks:20150726231436p:plain

パディングしたくない場合は、個々の DataArray ごとに DataFrame に変換すればよい。

ds['humidity'].to_dataframe()

f:id:sinhrks:20150726231444p:plain

まとめ

xray を使えば 多次元のラベル付きデータを多次元のまま、pandas に近い方法で扱うことができる。