表操作

本節では,1つまたは複数の入力テーブルから新しいテーブルを生成するために利用可能な高度な操作について述べる.これには


書類

説明する.

機能

Grouped operations

表と列をキーでグループ化する

group_by

Binning

箱詰め台.

group_by

Stack vertically

行に沿って入力テーブルを接続する

vstack

Stack horizontally

列に沿って入力テーブルを接続する

hstack

Join

2つの表のデータベース接続

join

Unique rows

ボタン配列の唯一の表行

unique

Set difference

2つの表の違いを設定する

setdiff

Table diff

2つの簡単な表の一般的な違い

report_diff_values

グループ化操作

表や表列では,データセットの自然グループがいくつかの派生値を計算することは意味がある場合がある.最小の例は、様々な観測動作からの光度を有するオブジェクトリストである。

>>> from astropy.table import Table
>>> obs = Table.read("""name    obs_date    mag_b  mag_v
...                     M31     2012-01-02  17.0   17.5
...                     M31     2012-01-02  17.1   17.4
...                     M101    2012-01-02  15.1   13.5
...                     M82     2012-02-14  16.2   14.5
...                     M31     2012-02-14  16.9   17.3
...                     M82     2012-02-14  15.2   15.5
...                     M101    2012-02-14  15.0   13.6
...                     M82     2012-03-26  15.7   16.5
...                     M101    2012-03-26  15.1   13.5
...                     M101    2012-03-26  14.8   14.3
...                     """, format='ascii')

表組.

それぞれの物体の平均震度を想定してみましょうまずデータを押して name 列の中の group_by() 方法です。これは,以下の条件でソートされた新しい表を返す. name これは1つあります groups 属性、その属性指定 name 対応する表行:

>>> obs_by_name = obs.group_by('name')
>>> print(obs_by_name)  
name  obs_date  mag_b mag_v
---- ---------- ----- -----
M101 2012-01-02  15.1  13.5  << First group (index=0, key='M101')
M101 2012-02-14  15.0  13.6
M101 2012-03-26  15.1  13.5
M101 2012-03-26  14.8  14.3
 M31 2012-01-02  17.0  17.5  << Second group (index=4, key='M31')
 M31 2012-01-02  17.1  17.4
 M31 2012-02-14  16.9  17.3
 M82 2012-02-14  16.2  14.5  << Third group (index=7, key='M83')
 M82 2012-02-14  15.2  15.5
 M82 2012-03-26  15.7  16.5
                             << End of groups (index=10)
>>> print(obs_by_name.groups.keys)
name
----
M101
 M31
 M82
>>> print(obs_by_name.groups.indices)
[ 0  4  7 10]

The groups property is the portal to all grouped operations with tables and columns. It defines how the table is grouped via an array of the unique row key values and the indices of the group boundaries for those key values. The groups here correspond to the row slices 0:4, 4:7, and 7:10 in the obs_by_name table.

最初の論点は (keys ) group_by 関数は、様々な入力データタイプを使用することができる:

  • 表列名を有する単一文字列値(以上のように)

  • リスト名を有する文字列値リスト

  • もう一つは Table あるいは…。 Column テーブルと同じ長さだ

  • numpy 表と同じ長さの構造化配列

  • numpy 表と同じ長さの同一配列

すべての場合、対応する行要素は、元のテーブルを順序付けして必要なグループを生成するためのキー値を形成する値のタプルとみなされる。

たとえば,観測夜ごとの対象ごとの平均星を得るなど,まずこの2つの対象の表をグループ化する. name そして obs_date 詳細は以下のとおりである.

>>> print(obs.group_by(['name', 'obs_date']).groups.keys)
name  obs_date
---- ----------
M101 2012-01-02
M101 2012-02-14
M101 2012-03-26
 M31 2012-01-02
 M31 2012-02-14
 M82 2012-02-14
 M82 2012-03-26

操縦班.

パケットがテーブルに適用されると、各グループまたはグループのサブセットにアクセスすることができる。すべての場合、これは新しいパケットテーブルに戻るだろう。例えば、第2のグループ(index=1)に対応するサブテーブルを取得するためには、以下の動作が実行される。

>>> print(obs_by_name.groups[1])
name  obs_date  mag_b mag_v
---- ---------- ----- -----
 M31 2012-01-02  17.0  17.5
 M31 2012-01-02  17.1  17.4
 M31 2012-02-14  16.9  17.3

第1のグループと第2のグループを組み合わせるには、スライスを使用してください:

>>> groups01 = obs_by_name.groups[0:2]
>>> print(groups01)
name  obs_date  mag_b mag_v
---- ---------- ----- -----
M101 2012-01-02  15.1  13.5
M101 2012-02-14  15.0  13.6
M101 2012-03-26  15.1  13.5
M101 2012-03-26  14.8  14.3
 M31 2012-01-02  17.0  17.5
 M31 2012-01-02  17.1  17.4
 M31 2012-02-14  16.9  17.3
>>> print(groups01.groups.keys)
name
----
M101
 M31

あなたはまた一つを提供することができます numpy 特定のグループを選択するためのインデックス配列またはブーリアンマスク、例えば、:

>>> mask = obs_by_name.groups.keys['name'] == 'M101'
>>> print(obs_by_name.groups[mask])
name  obs_date  mag_b mag_v
---- ---------- ----- -----
M101 2012-01-02  15.1  13.5
M101 2012-02-14  15.0  13.6
M101 2012-03-26  15.1  13.5
M101 2012-03-26  14.8  14.3

使用することができます:グループ表と対応するキーをトラバースする

>>> for key, group in zip(obs_by_name.groups.keys, obs_by_name.groups):
...     print(f'****** {key["name"]} *******')
...     print(group)
...     print('')
...
****** M101 *******
name  obs_date  mag_b mag_v
---- ---------- ----- -----
M101 2012-01-02  15.1  13.5
M101 2012-02-14  15.0  13.6
M101 2012-03-26  15.1  13.5
M101 2012-03-26  14.8  14.3
****** M31 *******
name  obs_date  mag_b mag_v
---- ---------- ----- -----
 M31 2012-01-02  17.0  17.5
 M31 2012-01-02  17.1  17.4
 M31 2012-02-14  16.9  17.3
****** M82 *******
name  obs_date  mag_b mag_v
---- ---------- ----- -----
 M82 2012-02-14  16.2  14.5
 M82 2012-02-14  15.2  15.5
 M82 2012-03-26  15.7  16.5

列組.

Table 相手は、 Column パケット化動作によって後続の動作を行うために、オブジェクトをグループ化することもできる。これは同時に応用することができます Table 丸裸になっているのではないでしょうか Column 物体です。

そこまでは Table 使用します group_by 方法です。ここでの違いは、これは、1つまたは複数の列名のオプションが提供されていないことである。 Column それがそうです。

実例.

列でパケットを生成するには、以下の動作を実行してください。

>>> from astropy.table import Column
>>> import numpy as np
>>> c = Column([1, 2, 3, 4, 5, 6], name='a')
>>> key_vals = np.array(['foo', 'bar', 'foo', 'foo', 'qux', 'qux'])
>>> cg = c.group_by(key_vals)

>>> for key, group in zip(cg.groups.keys, cg.groups):
...     print(f'****** {key} *******')
...     print(group)
...     print('')
...
****** bar *******
 a
---
  2
****** foo *******
 a
---
  1
  3
  4
****** qux *******
 a
---
  5
  6

重合する.

Aggregation is the process of applying a specified reduction function to the values within each group for each non-key column. This function must accept a numpy array as the first argument and return a single scalar value. Common function examples are numpy.sum, numpy.mean, and numpy.std.

サンプルパケット表の場合 obs_by_name 上から始めましょう aggregate 方法:

>>> obs_mean = obs_by_name.groups.aggregate(np.mean)  
WARNING: Cannot aggregate column 'obs_date' [astropy.table.groups]
>>> print(obs_mean)  
name mag_b mag_v
---- ----- ------
M101  15.0 13.725
 M31  17.0   17.4
 M82  15.7   15.5

震度値は平均値を求めることに成功しているように見えるが、警告とはどういうことなのだろうか。以来. obs_date 列が文字列タイプの配列であれば numpy.mean 関数が失敗して異常を引き起こす.いつでもこんなことが起こる aggregate 警告を発し,出力結果からその列を削除する.注意してください。 name 列は? keys 集約から自動的に無視するために、パケットを決定するために使用される。

パケットテーブルから、集約を実行する1つまたは複数の列を選択することができる:

>>> print(obs_by_name['mag_b'].groups.aggregate(np.mean))  
      mag_b
------------------
15.000000000000002
              17.0
15.699999999999998

>>> print(obs_by_name['name', 'mag_v', 'mag_b'].groups.aggregate(np.mean))  
name       mag_v              mag_b
---- ------------------ ------------------
M101 13.725000000000001 15.000000000000002
 M31 17.400000000000002               17.0
 M82               15.5 15.699999999999998

単一列データを集約することもできます:

>>> c = Column([1, 2, 3, 4, 5, 6], name='a')
>>> key_vals = np.array(['foo', 'bar', 'foo', 'foo', 'qux', 'qux'])
>>> cg = c.group_by(key_vals)
>>> cg_sums = cg.groups.aggregate(np.sum)
>>> for key, cg_sum in zip(cg.groups.keys, cg_sums):
...     print(f'Sum for {key} = {cg_sum}')
...
Sum for bar = 2
Sum for foo = 8
Sum for qux = 11

指定された関数があれば numpy.ufunc.reduceat メソッドは,このメソッドを呼び出すように変更する.比較的小さいグループの多くの大型非マスクを有するテーブルまたは列の場合、これは、10~100倍(またはそれ以上)の性能を向上させることができる。何かを使うことも許可されています `numpy 一般に、複数の入力配列を受け取るが、簡略化関数の関数としても使用される。 numpy.add それがそうです。♪the numpy 以下の機能を利用すべき関数: numpy.ufunc.reduceat 内容:

特別な場合には numpy.sum そして numpy.mean それぞれのものに置き換える reduceat 方法です。

濾過除去.

表グループは、以下のように選択することができる。 filter 方法です。これは,グループごとに呼び出される関数を提供することで実現される.この方法に渡される関数は、2つのパラメータを受け入れなければならない。

  • tableTable 客体.

  • key_colnames :中の列リスト table グループのキーとして使う

そして戻らなければなりません True あるいは…。 False それがそうです。

例を引く

次に、非キー列に正の値のみが含まれるすべてのテーブルグループを選択する。

>>> def all_positive(table, key_colnames):
...     colnames = [name for name in table.colnames if name not in key_colnames]
...     for colname in colnames:
...         if np.any(table[colname] < 0):
...             return False
...     return True

この関数を用いた例は以下のとおりである.

>>> t = Table.read(""" a   b    c
...                   -2  7.0   0
...                   -2  5.0   1
...                    1  3.0  -5
...                    1 -2.0  -6
...                    1  1.0   7
...                    0  0.0   4
...                    3  3.0   5
...                    3 -2.0   6
...                    3  1.0   7""", format='ascii')
>>> tg = t.group_by('a')
>>> t_positive = tg.groups.filter(all_positive)
>>> for group in t_positive.groups:
...     print(group)
...     print('')
...
 a   b   c
--- --- ---
 -2 7.0   0
 -2 5.0   1

 a   b   c
--- --- ---
  0 0.0   4

ご覧のように a == -2 そして a == 0 非キー列にはすべての正の値が含まれているので,これらの値を選択する.

同様に使用可能です filter 方法であるが、本例では、フィルタ関数は、1つのパラメータ、すなわち列グループのみを受け取る。まだ戻らなければなりません True あるいは…。 False それがそうです。例えば:

def all_positive(column):
    if np.any(column < 0):
        return False
    return True

箱詰めする.

分析中の常用ツールの1つはいくつかの参考値に基づいて表を入庫することである。例えば:

  • 1つの双星が一定期間撮影したいくつかの帯域の測光は、軌道位相で分類すべきである。

  • テーブルのサンプリング密度は、100行を1回マージすることで低減される。

  • 不均一な履歴データをサンプリングし,毎年4つの点に分類すべきである.

これらの箱時計の例はすべて使用可能です grouped operations それがそうです。この部分の例は、ソースの名前のような離散キー値の場合に重点を置いている。本節では、時間、段階、または行番号などのキーワード値のバインディングを完了するために、グループ化動作を適用する簡潔で強力な方法を示す。

これらすべての共通トピックは,鍵値配列を新たな浮動小数点配列または整数配列に変換し,その値は同一出力ボックス中の行に対して同じである.

例を引く

例えば偽のライト曲線を生成します

>>> year = np.linspace(2000.0, 2010.0, 200)  # 200 observations over 10 years
>>> period = 1.811
>>> y0 = 2005.2
>>> mag = 14.0 + 1.2 * np.sin(2 * np.pi * (year - y0) / period)
>>> phase = ((year - y0) / period) % 1.0
>>> dat = Table([year, phase, mag], names=['year', 'phase', 'mag'])

さて、0.25年間隔でデータを入庫するための配列を作成します。

>>> year_bin = np.trunc(year / 0.25)

これは,0.25年binのすべてのサンプルが持つ属性を持ち,その属性の値と year_bin それがそうです。考えてみて year_bin 倉号として year それがそうです。そしてグループ化してすぐに集約することで箱詰めします np.mean それがそうです。

>>> dat_grouped = dat.group_by(year_bin)
>>> dat_binned = dat_grouped.groups.aggregate(np.mean)

結果図を描くことができます plt.plot(dat_binned['year'], dat_binned['mag'], '.') それがそうです。あるいは10個の位相ボックスに分けることができます

>>> phase_bin = np.trunc(phase / 0.1)
>>> dat_grouped = dat.group_by(phase_bin)
>>> dat_binned = dat_grouped.groups.aggregate(np.mean)

今回は、ご利用ください plt.plot(dat_binned['phase'], dat_binned['mag']) それがそうです。

垂直スタック

♪the Table クラスは、垂直スタッキングテーブルをサポートします。 vstack 機能します。このプロセスは、一般に、行方向に接続または追加テーブルとも呼ばれる。基本的には numpy.vstack 機能します。

実例.

2つの観察表があるとしましょういくつかの共通の列名があります

>>> from astropy.table import Table, vstack
>>> obs1 = Table.read("""name    obs_date    mag_b  logLx
...                      M31     2012-01-02  17.0   42.5
...                      M82     2012-10-29  16.2   43.5
...                      M101    2012-10-31  15.1   44.5""", format='ascii')

>>> obs2 = Table.read("""name    obs_date    logLx
...                      NGC3516 2011-11-11  42.1
...                      M31     1999-01-05  43.1
...                      M82     2012-10-30  45.0""", format='ascii')

この2つの表を積むことができます

>>> print(vstack([obs1, obs2]))
  name   obs_date  mag_b logLx
------- ---------- ----- -----
    M31 2012-01-02  17.0  42.5
    M82 2012-10-29  16.2  43.5
   M101 2012-10-31  15.1  44.5
NGC3516 2011-11-11    --  42.1
    M31 1999-01-05    --  43.1
    M82 2012-10-30    --  45.0

気がつく obs2 表に欠けている mag_b 列,したがって,スタック出力テーブルでは,これらの値は欠落とラベル付けされる.これはデフォルトの行為であり join_type='outer' それがそうです。属性の他の2つの許容値. join_type 論点は 'inner' そして 'exact' **

>>> print(vstack([obs1, obs2], join_type='inner'))
  name   obs_date  logLx
------- ---------- -----
    M31 2012-01-02  42.5
    M82 2012-10-29  43.5
   M101 2012-10-31  44.5
NGC3516 2011-11-11  42.1
    M31 1999-01-05  43.1
    M82 2012-10-30  45.0

>>> print(vstack([obs1, obs2], join_type='exact'))  
Traceback (most recent call last):
  ...
TableMergeError: Inconsistent columns in input arrays (use 'inner'
or 'outer' join_type to allow non-matching columns)

.の場合 join_type='inner' ,出力表には共通列(交叉点)のみがある.いつですか join_type='exact' 指定されています vstack すべての入力テーブルがまったく同じ列名を持つことが要求される.

表オブジェクトリストを提供することにより、2つ以上のテーブルをスタックすることができる。

>>> obs3 = Table.read("""name    obs_date    mag_b  logLx
...                      M45     2012-02-03  15.0   40.5""", format='ascii')
>>> print(vstack([obs1, obs2, obs3]))
  name   obs_date  mag_b logLx
------- ---------- ----- -----
    M31 2012-01-02  17.0  42.5
    M82 2012-10-29  16.2  43.5
   M101 2012-10-31  15.1  44.5
NGC3516 2011-11-11    --  42.1
    M31 1999-01-05    --  43.1
    M82 2012-10-30    --  45.0
    M45 2012-02-03  15.0  40.5

別項参照 Merging metadata そして Merging column attributes 入力テーブルのこれらの特徴を単一の出力テーブルにどのように統合するかに関する詳細な情報.なお、入力の1つとして、表全体ではなく、単一の表行を使用することができます。

水平スタック.

♪the Table クラスサポートレベル(列方向)スタックテーブル. hstack 機能します。基本的には numpy.hstack 機能します。

実例.

次の2つの表があるとしましょう

>>> from astropy.table import Table, hstack
>>> t1 = Table.read("""a   b    c
...                    1   foo  1.4
...                    2   bar  2.1
...                    3   baz  2.8""", format='ascii')
>>> t2 = Table.read("""d     e
...                    ham   eggs
...                    spam  toast""", format='ascii')

この2つの表を水平に積むことができます

>>> print(hstack([t1, t2]))
 a   b   c   d     e
--- --- --- ---- -----
  1 foo 1.4  ham  eggs
  2 bar 2.1 spam toast
  3 baz 2.8   --    --

As with vstack, there is an optional join_type argument that can take values 'inner', 'exact', and 'outer'. The default is 'outer', which effectively takes the union of available rows and masks out any missing values. This is illustrated in the example above. The other options give the intersection of rows, where 'exact' requires that all tables have exactly the same number of rows:

>>> print(hstack([t1, t2], join_type='inner'))
 a   b   c   d     e
--- --- --- ---- -----
  1 foo 1.4  ham  eggs
  2 bar 2.1 spam toast

>>> print(hstack([t1, t2], join_type='exact'))  
Traceback (most recent call last):
  ...
TableMergeError: Inconsistent number of rows in input arrays (use 'inner' or
'outer' join_type to allow non-matching rows)

表オブジェクトリストを提供することにより、2つ以上のテーブルをスタックすることができる。以下の例では、列名が衝突した場合の動作も説明されています(参照 Column renaming 詳細について):

>>> t3 = Table.read("""a    b
...                    M45  2012-02-03""", format='ascii')
>>> print(hstack([t1, t2, t3]))
a_1 b_1  c   d     e   a_3    b_3
--- --- --- ---- ----- --- ----------
  1 foo 1.4  ham  eggs M45 2012-02-03
  2 bar 2.1 spam toast  --         --
  3 baz 2.8   --    --  --         --

入力テーブル中のメタデータは、中に記述されたプロセスによって統合される Merging metadata 一節です。なお、入力の1つとして、表全体ではなく、単一の表行を使用することができます。

スタック深さ-WISE

♪the Table クラスサポート使用 dstack 機能します。これは大体運行に相当します numpy.dstack 関数は名前ごとにマッチする各列に作用する.

実例.

異なるPSFスコアのクローズドソースカウントの情報が提供されるソースデータテーブルがあると仮定する。

>>> from astropy.table import Table, dstack
>>> src1 = Table.read("""psf_frac  counts
...                      0.10        45
...                      0.50        90
...                      0.90       120
...                      """, format='ascii')

>>> src2 = Table.read("""psf_frac  counts
...                      0.10       200
...                      0.50       300
...                      0.90       350
...                      """, format='ascii')

ここで、2つのテーブルを深さに沿ってスタックして、2つのソースの特徴を有する単一のテーブルを得ることができる:

>>> srcs = dstack([src1, src2])
>>> print(srcs)
psf_frac [2] counts [2]
------------ ----------
  0.1 .. 0.1  45 .. 200
  0.5 .. 0.5  90 .. 300
  0.9 .. 0.9 120 .. 350

この場合、第1のソースのカウントは、 srcs['counts'][:, 0] 同様に、2番目のソース数は srcs['counts'][:, 1] それがそうです。

この関数に対して,すべての入力テーブルの長さは同じでなければならない.この関数は受け入れられます join_type そして metadata_conflicts まるで vstack 機能します。♪the join_type パラメータ制御入力テーブルの列中の不一致をどのように処理するか.

別項参照 Merging metadata そして Merging column attributes 入力テーブルのこれらの特徴を単一の出力テーブルにどのように統合するかに関する詳細な情報.なお、入力の1つとして、表全体ではなく、単一の表行を使用することができます。

合流する.

♪the Table 類支持. database join 手術です。これは、1つまたは複数のキー列に基づく値組合せテーブルに基づいて柔軟で強力な方法を提供する。

実例.

2つの観察テーブルがあると仮定すると、第1のテーブルはBおよびVなどを有し、第2のテーブルは重複(ではあるが完全に同じではない)サンプルのX線輝度を有する。

>>> from astropy.table import Table, join
>>> optical = Table.read("""name    obs_date    mag_b  mag_v
...                         M31     2012-01-02  17.0   16.0
...                         M82     2012-10-29  16.2   15.2
...                         M101    2012-10-31  15.1   15.5""", format='ascii')
>>> xray = Table.read("""   name    obs_date    logLx
...                         NGC3516 2011-11-11  42.1
...                         M31     1999-01-05  43.1
...                         M82     2012-10-29  45.0""", format='ascii')

♪the join() 方法により、“キー列”の適合値に基づいて、この2つのテーブルを1つのテーブルに統合することができます。デフォルトの場合,キー列は2つの表が共有する1組の列である.本例では、キー列は name そして obs_date それがそうです。同じ日に同じ天体のすべての観測結果を見つけることができます

>>> opt_xray = join(optical, xray)
>>> print(opt_xray)
name  obs_date  mag_b mag_v logLx
---- ---------- ----- ----- -----
 M82 2012-10-29  16.2  15.2  45.0

以下のように試合を行うことができます name 提供するだけで keys パラメータは、単一の列名であってもよく、1組の列名であってもよい:

>>> print(join(optical, xray, keys='name'))
name obs_date_1 mag_b mag_v obs_date_2 logLx
---- ---------- ----- ----- ---------- -----
 M31 2012-01-02  17.0  16.0 1999-01-05  43.1
 M82 2012-10-29  16.2  15.2 2012-10-29  45.0

この出力テーブルは、対象(M 31およびM 82)を有する光学およびX線データのすべての観測データを含む。注意してください obs_date 現在2つの表を並べて2つの列に分割されています obs_date_1 そして obs_date_2 それがそうです。これらの値は“左”からとる. (optical )と“そう” (xray )時計。

異なる連結オプション

これまで,表接続は“内部”接続と呼ばれ,2つの表のキー列上の厳密な交わりを示してきた.

新しい表を作成したいなら、この表は 間隔を置いて 左テーブルの行は、利用可能である場合、右テーブル内の一致値を含み、これを左連結と呼ぶ:

>>> print(join(optical, xray, join_type='left'))
name  obs_date  mag_b mag_v logLx
---- ---------- ----- ----- -----
M101 2012-10-31  15.1  15.5    --
 M31 2012-01-02  17.0  16.0    --
 M82 2012-10-29  16.2  15.2  45.0

2つの観測にはX線データがありません -- テーブルの上にあります。任意の値が欠落している場合、出力はマスクテーブルとなる(参照)。 マスクと欠損値 より多くの情報を得る)。あなたは出力にM 31のX線データがないことに驚くかもしれない。デフォルトキーにはこの2つのキーが含まれていることを覚えておいてください name そして obs_date それがそうです。このキーを単に指定する name 列は以下のように与えられます

>>> print(join(optical, xray, join_type='left', keys='name'))
name obs_date_1 mag_b mag_v obs_date_2 logLx
---- ---------- ----- ----- ---------- -----
M101 2012-10-31  15.1  15.5         --    --
 M31 2012-01-02  17.0  16.0 1999-01-05  43.1
 M82 2012-10-29  16.2  15.2 2012-10-29  45.0

同様に、以下のコマンドを使用して、右テーブルの各行および一致する左の値を含む新しいテーブルを構築することができる(利用可能であれば)。 join_type='right' それがそうです。

2つのテーブルの行和セットを含むテーブルを作成するには、“外部”接続を実行してください。

>>> print(join(optical, xray, join_type='outer'))
  name   obs_date  mag_b mag_v logLx
------- ---------- ----- ----- -----
   M101 2012-10-31  15.1  15.5    --
    M31 1999-01-05    --    --  43.1
    M31 2012-01-02  17.0  16.0    --
    M82 2012-10-29  16.2  15.2  45.0
NGC3516 2011-11-11    --    --  42.1

上記のすべての場合,出力接続テーブルはキー列でソートされ,通常は入力テーブルの行順序を保持しない.

最後に、すべての利用可能な行のデカルト積である“デカルト”接続を実行することができます。本例では、キー列はない(提供する) keys パラメータエラー)::

>>> print(join(optical, xray, join_type='cartesian'))
name_1 obs_date_1 mag_b mag_v  name_2 obs_date_2 logLx
------ ---------- ----- ----- ------- ---------- -----
   M31 2012-01-02  17.0  16.0 NGC3516 2011-11-11  42.1
   M31 2012-01-02  17.0  16.0     M31 1999-01-05  43.1
   M31 2012-01-02  17.0  16.0     M82 2012-10-29  45.0
   M82 2012-10-29  16.2  15.2 NGC3516 2011-11-11  42.1
   M82 2012-10-29  16.2  15.2     M31 1999-01-05  43.1
   M82 2012-10-29  16.2  15.2     M82 2012-10-29  45.0
  M101 2012-10-31  15.1  15.5 NGC3516 2011-11-11  42.1
  M101 2012-10-31  15.1  15.5     M31 1999-01-05  43.1
  M101 2012-10-31  15.1  15.5     M82 2012-10-29  45.0

キー列の名前が違います

♪the join() 関数は,2つの表中のキー列名が同じであることを要求する.しかし,次のコードには,1つの表がある. 'name' 列は別の列は 'obj_id' コラム::

>>> optical = Table.read("""name    obs_date    mag_b  mag_v
...                         M31     2012-01-02  17.0   16.0
...                         M82     2012-10-29  16.2   15.2
...                         M101    2012-10-31  15.1   15.5""", format='ascii')
>>> xray_1 = Table.read("""   obj_id    obs_date    logLx
...                           NGC3516 2011-11-11  42.1
...                           M31     1999-01-05  43.1
...                           M82     2012-10-29  45.0""", format='ascii')

オブジェクト名に応じてマッチングを行うためには、新しいテーブルを作成する前に、上述した列のうちの1つを一時的にリネーミングする必要があります。

>>> xray_1.rename_column('obj_id', 'name')
>>> opt_xray_1 = join(optical, xray_1, keys='name')
>>> xray_1.rename_column('name', 'obj_id')
>>> print(opt_xray_1)
name obs_date_1 mag_b mag_v obs_date_2 logLx
---- ---------- ----- ----- ---------- -----
M31 2012-01-02  17.0  16.0 1999-01-05  43.1
M82 2012-10-29  16.2  15.2 2012-10-29  45.0

原版. xray_1 表は操作後不変である:

>>> print(xray_1)
obj_id  obs_date  logLx
------- ---------- -----
NGC3516 2011-11-11  42.1
    M31 1999-01-05  43.1
    M82 2012-10-29  45.0

同じ鍵値

♪the Table 複数行が同じキー値を持っていても,リンク操作は有効である.たとえば,次の表のキー列は複数行ある. x **

>>> from astropy.table import Table, join
>>> left = Table([[0, 1, 1, 2], ['L1', 'L2', 'L3', 'L4']], names=('key', 'L'))
>>> right = Table([[1, 1, 2, 4], ['R1', 'R2', 'R3', 'R4']], names=('key', 'R'))
>>> print(left)
key  L
--- ---
  0  L1
  1  L2
  1  L3
  2  L4
>>> print(right)
key  R
--- ---
  1  R1
  1  R2
  2  R3
  4  R4

これらの表で外部接続を行うと実際に起きているのは Cartesian product それがそうです。各マッチングキーについて,左表と右表の各組合せを示す.左テーブルまたは右テーブルに一致項がない場合、対応する列値は欠落として指定される。

>>> print(join(left, right, join_type='outer'))
key  L   R
--- --- ---
  0  L1  --
  1  L2  R1
  1  L2  R2
  1  L3  R1
  1  L3  R2
  2  L4  R3
  4  --  R4

注釈

出力表はキー列でソートされているが,同じ鍵を持つ行が存在する場合,非鍵列における出力順序が異なる実装で同じである保証はない.上記の例では、4行の順序 key == 1 違うかもしれません。

内部リンクは同じであるが、左テーブルと右テーブルの両方にキーマッチングがある行のみに戻る:

>>> print(join(left, right, join_type='inner'))
key  L   R
--- --- ---
  1  L2  R1
  1  L2  R2
  1  L3  R1
  1  L3  R2
  2  L4  R3

入力表名における衝突は前節で紹介したプロセスによって処理される. Column renaming それがそうです。別項参照 Merging metadata そして Merging column attributes 入力テーブルのこれらの特徴を単一の出力テーブルにどのように統合するかに関する詳細な情報.

詳細を統合しています

2つ以上のテーブルを組み合わせる場合、入力中のいくつかの特徴を統合し、衝突を潜在的に解決する必要がある。本節では,この過程について述べる.

名前を列重する.

入力テーブルが衝突列名を持つ場合には,唯一の出力列名を生成できる機構がある.リネーミング行動を制御する2つのキーワードパラメータがあります

table_names

連結するテーブルに名前の2要素文字列リストを提供します。デフォルトではこれは ['1', '2', ...] ここで、数字は入力テーブルに対応する。

uniq_col_name

文字列フォーマット説明子、デフォルト値は '{{col_name}}_{{table_name}}' それがそうです。

この点については,使用することで optical そして xray 中の表 join() 先に定義した例:

>>> print(join(optical, xray, keys='name',
...            table_names=['OPTICAL', 'XRAY'],
...            uniq_col_name='{table_name}_{col_name}'))
name OPTICAL_obs_date mag_b mag_v XRAY_obs_date logLx
---- ---------------- ----- ----- ------------- -----
 M31       2012-01-02  17.0  16.0    1999-01-05  43.1
 M82       2012-10-29  16.2  15.2    2012-10-29  45.0

メタデータを統合する

Table オブジェクトは、関連するメタデータを有することができる:

  • Table.meta :表レベルのメタデータを順序辞書とする

  • Column.meta :順序辞書としてのメタデータ列ごと

ここで説明するテーブル動作処理は、入力テーブル内のメタデータを単一の出力構造内のタスクに統合する。メタデータは任意に複雑である可能性があるため,唯一の方式は統合されていない.4つのルールを有する再帰的アルゴリズムを使用することが現在実施されている:

  • dict 要素ボタン統合。

  • 相互衝突の list あるいは…。 tuple 元素は直列に接続されている。

  • 相互衝突の dict Merge関数を再帰的に呼び出すことで要素をマージする.

  • Conflicting elements that are not both list, tuple, or dict will follow the following rules:

    • 2つのメタデータ値が同じであれば、出力はこの値に設定される。

    • 衝突するメタデータの値の1つが None すると,別の値がピックアップされる.

    • 2つのメタデータの値が異なっていても異なる場合 None リスト中の最後の表の表を選択します。

By default, a warning is emitted in the last case (both metadata values are not None). The warning can be silenced or made into an exception using the metadata_conflicts argument to hstack(), vstack(), or join(). The metadata_conflicts option can be set to:

  • 'silent' −警告は出さず、最後のテーブルの値は静かにピックアップされる。

  • 'warn' -警告を発し、最後のテーブルの値を選択します。

  • 'error' -異常を誘発します。

定義されたサブクラスにより,結合メタデータのデフォルトポリシーを拡張またはカスタマイズすることができる. MergeStrategy 基本類です。ほとんどの場合、あなたはまた使用します enable_merge_strategies カスタムポリシーを有効にするために使用されます。リンクされた文書文字列は詳細な情報を提供する.

合併列属性

In addition to the table and column meta attributes, the column attributes unit, format, and description are merged by going through the input tables in order and taking the first value which is defined (i.e., is not None).

例を引く

To merge column attributes unit, format, or description:

>>> from astropy.table import Column, Table, vstack
>>> col1 = Column([1], name='a')
>>> col2 = Column([2], name='a', unit='cm')
>>> col3 = Column([3], name='a', unit='m')
>>> t1 = Table([col1])
>>> t2 = Table([col2])
>>> t3 = Table([col3])
>>> out = vstack([t1, t2, t3])  
WARNING: MergeConflictWarning: In merged column 'a' the 'unit' attribute does
not match (cm != m).  Using m for merged output [astropy.table.operations]
>>> out['a'].unit  
Unit("m")

統合の規則と Merging metadata そして、 metadata_conflicts オプションはまた,列属性の統合を制御する.

接続座標とカスタム接続機能

2つのソースディレクトリがあれば、この2つのソースディレクトリは SkyCoord 座標列は、指定された距離閾値を有する座標の交差マッチングを用いてこれらの列を接続することができる。これは,キー列値の“ファジィ”マッチングというより一般的な問題の特例であり,この場合,正確なマッチングではなく近似的なマッチングのみが必要となる.これは使用することで join_funcs パラメータ(4.1版で導入).

例を引く

連結する2つの表は、以下の操作を実行してください SkyCoord キー列は join_funcs キーワードで提供します dict 特定のキー列をどのように名前でマッチさせるかを指定する関数.以下の例では sc 列,したがって,以下のパラメータを提供する.

join_funcs={'sc': join_skycoord(0.2 * u.deg)}

これは join 一致しなければならない sc カスタム結合関数キー列を用いて join_skycoord 0.2°の一致距離閾値を用いた。ボンネットの下ではこれがいわゆる search_around_sky あるいは…。 search_around_3d 交差照合を行う。デフォルト値は使用 'search_around_sky' (角度が)一致するが 'search_around_3d' (長さや無量綱)も利用可能である。これは使用です distance_func 論争する. join_skycoord また、入出力APIにマッチする関数であってもよい。 search_around_sky それがそうです。

全体の過程をお見せしましょう

>>> from astropy.coordinates import SkyCoord
>>> import astropy.units as u
>>> from astropy.table import Table, join, join_skycoord
>>> sc1 = SkyCoord([0, 1, 1.1, 2], [0, 0, 0, 0], unit='deg')
>>> sc2 = SkyCoord([1.05, 0.5, 2.1], [0, 0, 0], unit='deg')
>>> t1 = Table([sc1, [0, 1, 2, 3]], names=['sc', 'idx_1'])
>>> t2 = Table([sc2, [0, 1, 2]], names=['sc', 'idx_2'])
>>> t12 = join(t1, t2, join_funcs={'sc': join_skycoord(0.2 * u.deg)})
>>> print(t12)
sc_id   sc_1  idx_1   sc_2   idx_2
      deg,deg       deg,deg
----- ------- ----- -------- -----
    1 1.0,0.0     1 1.05,0.0     0
    1 1.1,0.0     2 1.05,0.0     0
    2 2.0,0.0     3  2.1,0.0     2

接続テーブルは、0.2度以内のソースと一致し、新しい列を作成しました sc_id 各ソースは一意の識別子を有する。

あなたは上で定義された結合関数で何が起こったのか知りたいかもしれません。特にあなたが自分のこのような関数を定義することに興味があれば。テーブルの曖昧なワードが一致することを可能にするために、例えば、名前が常に正確に一致するわけではない場合には、名前で担当者テーブルを接続することができる。

ここでまず注意しなければならないのは join_skycoord 関数は実際に関数自体を返す.これにより、機能ハウジングを介して可変マッチング距離を指定することができる。接続関数の要求は,2つの鍵列に対応する2つのパラメータを受け取り,返すことである. (ids1, ids2) それがそうです。これらの識別子は、一意の一致元を有する各列エントリの識別に対応する。

>>> join_func = join_skycoord(0.2 * u.deg)
>>> join_func(sc1, sc2)  # Associate each coordinate with unique source ID
(array([3, 1, 1, 2]), array([1, 4, 2]))

もしあなたが自分のファジィマッチング関数を作成したいなら、ソースコードから始めることをお勧めします join_skycoord あるいは…。 join_distance それがそうです。

距離で結ぶ

上の例はどうやって SkyCoord 属性リンク列の値間の一般的な距離. join_distance JOIN関数です。これは、1次元または2次元(ベクトル)列に適用することができる。これは座標例と非常に類似しているように見えるが、ここにはより多くの柔軟性がある。マッチングは使用 scipy.spatial.cKDTree そして scipy.spatial.cKDTree.query_ball_tree これらのコンポーネントの行動は kdtree_args そして query_args パラメータはそれぞれである.

唯一の行

表中の唯一のキー列を持つ行,さらには完全に唯一の行のみを用いることは意味がある場合がある.これは上で説明したものを使うことができます group_by() 方法と方法 groups 属性、または使用 unique 便利な機能。♪the unique 関数は、各一意のものを含む順序付けされたテーブルを返す keys 値を列記する。もしなければ keys 完全に唯一の行を含む順序表を返す.

例を引く

一意のキー列を有する行を使用したい場合の一例は、様々な観測動作からの光度を有するオブジェクトリストである。Vbl.使用 'name' 唯一の keys これは、以下の3つのオブジェクトの各オブジェクトの第1の適合項を返す:

>>> from astropy import table
>>> obs = table.Table.read("""name    obs_date    mag_b  mag_v
...                           M31     2012-01-02  17.0   17.5
...                           M82     2012-02-14  16.2   14.5
...                           M101    2012-01-02  15.1   13.5
...                           M31     2012-01-02  17.1   17.4
...                           M101    2012-01-02  15.1   13.5
...                           M82     2012-02-14  16.2   14.5
...                           M31     2012-02-14  16.9   17.3
...                           M82     2012-02-14  15.2   15.5
...                           M101    2012-02-14  15.0   13.6
...                           M82     2012-03-26  15.7   16.5
...                           M101    2012-03-26  15.1   13.5
...                           M101    2012-03-26  14.8   14.3
...                           """, format='ascii')
>>> unique_by_name = table.unique(obs, keys='name')
>>> print(unique_by_name)
name  obs_date  mag_b mag_v
---- ---------- ----- -----
M101 2012-01-02  15.1  13.5
 M31 2012-01-02  17.0  17.5
 M82 2012-02-14  16.2  14.5

多列を用いる keys **

>>> unique_by_name_date = table.unique(obs, keys=['name', 'obs_date'])
>>> print(unique_by_name_date)
name  obs_date  mag_b mag_v
---- ---------- ----- -----
M101 2012-01-02  15.1  13.5
M101 2012-02-14  15.0  13.6
M101 2012-03-26  15.1  13.5
 M31 2012-01-02  17.0  17.5
 M31 2012-02-14  16.9  17.3
 M82 2012-02-14  16.2  14.5
 M82 2012-03-26  15.7  16.5

差を設定する

セット差分は、別のセットに含まれる要素ではなく、1つのセットに含まれる要素を示す。この概念を表の行に適用することができ,方法は使用する setdiff 機能します。あなたは、第2のテーブルに現れない第1のテーブルのすべての行に戻る2つの入力テーブルを関数に提供する。

任意選択. keys パラメータは、マッチングテーブルの行の列の名前を指定します。これは、完全な列リストのサブセットであってもよいが、第1および第2のテーブルは、指定されたすべての列を含まなければならない。 keys それがそうです。提供されていない場合は keys デフォルトは最初の表のすべての列名です。

違う行が見つからなければ setdiff 関数は空のテーブルに戻ります。

例を引く

以下の例は、2つのテーブルの列の共通サブセットを使用して2つの観察リストのセット差異を検索する方法を示す。

>>> from astropy.table import Table, setdiff
>>> cat_1 = Table.read("""name    obs_date    mag_b  mag_v
...                       M31     2012-01-02  17.0   16.0
...                       M82     2012-10-29  16.2   15.2
...                       M101    2012-10-31  15.1   15.5""", format='ascii')
>>> cat_2 = Table.read("""   name    obs_date    logLx
...                          NGC3516 2011-11-11  42.1
...                          M31     2012-01-02  43.1
...                          M82     2012-10-29  45.0""", format='ascii')
>>> sdiff = setdiff(cat_1, cat_2, keys=['name', 'obs_date'])
>>> print(sdiff)
name  obs_date  mag_b mag_v
---- ---------- ----- -----
M101 2012-10-31  15.1  15.5

この例では、第1のテーブルのうちの1つは、第2のテーブルには存在しないので、 keys パラメータは必要な列名を指定するために用いなければならない.

表の違い

2つの時計を比較するには、ご利用いただけます report_diff_values() これは,以下と同様の報告を生成する. FITS diff それがそうです。

例を引く

以下の例は、2つのテーブル間の差異をどのように検索するかを示す。

>>> from astropy.table import Table
>>> from astropy.utils.diff import report_diff_values
>>> import sys
>>> cat_1 = Table.read("""name    obs_date    mag_b  mag_v
...                       M31     2012-01-02  17.0   16.0
...                       M82     2012-10-29  16.2   15.2
...                       M101    2012-10-31  15.1   15.5""", format='ascii')
>>> cat_2 = Table.read("""name    obs_date    mag_b  mag_v
...                       M31     2012-01-02  17.0   16.5
...                       M82     2012-10-29  16.2   15.2
...                       M101    2012-10-30  15.1   15.5
...                       NEW     2018-05-08   nan    9.0""", format='ascii')
>>> identical = report_diff_values(cat_1, cat_2, fileobj=sys.stdout)
     name  obs_date  mag_b mag_v
     ---- ---------- ----- -----
  a>  M31 2012-01-02  17.0  16.0
   ?                           ^
  b>  M31 2012-01-02  17.0  16.5
   ?                           ^
      M82 2012-10-29  16.2  15.2
  a> M101 2012-10-31  15.1  15.5
   ?               ^
  b> M101 2012-10-30  15.1  15.5
   ?               ^
  b>  NEW 2018-05-08   nan   9.0
>>> identical
False