2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FITSファイルの重複行を調査する方法とエンディアンに関する注意点

Posted at

はじめに

天文学の分野では、観測データをFITS(Flexible Image Transport System)形式で保存するのが一般的です。しかし、時にはデータ内に重複する行が含まれることがあります。本記事では、擬似的なFITSファイルを生成し、pandasを使って重複行を検出する方法を紹介します。

また、numpypandasのエンディアンの取り扱いに関する違いにも注意を向け、エンディアンの変換が必要な場合の対処法を解説します。


目次

  1. FITSファイルとエンディアンの取り扱いの違い
  2. 擬似FITSファイルの生成
  3. pandasを使った重複行の検出と保存
  4. エンディアンの確認と変換の方法
  5. サンプルコードと実行例

1. FITSファイルとエンディアンの取り扱いの違い

FITSファイルは、古いハードウェアや異なるプラットフォーム間の互換性を確保するため、ビッグエンディアン(Big-endian)形式 でデータを保存することが一般的です。
一方、numpypandasはデフォルトで リトルエンディアン(Little-endian) を使用します。

このエンディアンの不一致が原因で、pandasでデータを処理する際にエラーが発生することがあります。


2. 擬似FITSファイルの生成

以下のコードは、イベントデータを持つ擬似的なFITSファイルを生成します。

FITSファイル生成コード

create_mock_fits.py
from astropy.io import fits
import numpy as np

def create_mock_fits(filename):
    """Generate a mock FITS file with event data, including duplicates."""
    n_rows = 20
    time = np.concatenate([np.linspace(0, 19, 20), [10]])  # Duplicate TIME at 10
    itype = np.random.randint(0, 8, n_rows + 1)
    pixel = np.random.randint(0, 36, n_rows + 1)
    trig_lp = np.random.randint(0, 1000, n_rows + 1)
    deriv_max = np.random.randint(-32768, 32767, n_rows + 1)

    cols = [
        fits.Column(name='TIME', format='D', array=time),
        fits.Column(name='ITYPE', format='B', array=itype),
        fits.Column(name='PIXEL', format='B', array=pixel),
        fits.Column(name='TRIG_LP', format='J', array=trig_lp),
        fits.Column(name='DERIV_MAX', format='I', array=deriv_max)
    ]

    hdu = fits.BinTableHDU.from_columns(cols)
    hdu.writeto(filename, overwrite=True)
    print(f"Mock FITS file created: {filename}")

create_mock_fits('mock_event_data.fits')

3. pandasを使った重複行の検出と保存

以下のコードは、FITSファイルからデータを読み込み、TIMEに基づいて重複行を検出し、新しいFITSファイルに保存します。

重複行の検出コード

find_duplicates.py
from astropy.io import fits
import pandas as pd

def load_fits_to_dataframe(fits_file):
    """Load FITS data into a pandas DataFrame with endian conversion."""
    with fits.open(fits_file) as hdul:
        data = hdul[1].data
        # Ensure all data is converted to Little-endian for pandas compatibility
        df = pd.DataFrame({
            'TIME': data['TIME'].byteswap().newbyteorder(),
            'ITYPE': data['ITYPE'].byteswap().newbyteorder(),
            'PIXEL': data['PIXEL'].byteswap().newbyteorder(),
            'TRIG_LP': data['TRIG_LP'].byteswap().newbyteorder(),
            'DERIV_MAX': data['DERIV_MAX'].byteswap().newbyteorder()
        })
    return df

def find_and_save_duplicates(df, output_file):
    """Find duplicate rows based on 'TIME' and save them to a new FITS file."""
    duplicates = df[df.duplicated('TIME', keep=False)]
    print(f"Found {len(duplicates)} duplicate rows.")

    if not duplicates.empty:
        hdu = fits.BinTableHDU.from_columns([
            fits.Column(name='TIME', format='D', array=duplicates['TIME']),
            fits.Column(name='ITYPE', format='B', array=duplicates['ITYPE']),
            fits.Column(name='PIXEL', format='B', array=duplicates['PIXEL']),
            fits.Column(name='TRIG_LP', format='J', array=duplicates['TRIG_LP']),
            fits.Column(name='DERIV_MAX', format='I', array=duplicates['DERIV_MAX'])
        ])
        hdu.writeto(output_file, overwrite=True)
        print(f"Duplicate rows saved to {output_file}")

df = load_fits_to_dataframe('mock_event_data.fits')
find_and_save_duplicates(df, 'duplicates.fits')

4. エンディアンの確認と変換の方法

エンディアンの確認

以下のコードで、numpy配列のエンディアンを確認できます。

print(df['TIME'].dtype)  # >f8: Big-endian, <f8: Little-endian
  • >f8:Big-endian
  • <f8:Little-endian

エンディアンの変換

以下のように、byteswap()newbyteorder()を使ってエンディアンを変換します。

df['TIME'] = df['TIME'].byteswap().newbyteorder()

5. サンプルコードと実行例

実行手順

  1. 擬似FITSファイルを生成:

    python create_mock_fits.py
    

    FITSファイルの中身をftlistを用いて確認します。

> ftlist mock_event_data.fits
Print options: H C K I T [C] T

                       TIME ITYP PIXE     TRIG_LP DERIV_
                                                        
  1        0.00000000000000    4   28         503 -14406
  2        1.00000000000000    1   26         368   5503
  3        2.00000000000000    6   19         350  -3004
  4        3.00000000000000    4   31         948  32573
  5        4.00000000000000    7    0         494 -14526
  6        5.00000000000000    5   32          51 -29495
  7        6.00000000000000    7    9         496 -25354
  8        7.00000000000000    5    9         572  32754
  9        8.00000000000000    3   24          51  14589
 10        9.00000000000000    2   32         658 -13708
 11        10.0000000000000    7    2         294  32600
 12        11.0000000000000    7   10         281 -27159
 13        12.0000000000000    2   11         703  27509
 14        13.0000000000000    2   14         283   7499
 15        14.0000000000000    7   24         802  30085
 16        15.0000000000000    1    4         897  22922
 17        16.0000000000000    5   33         939 -30371
 18        17.0000000000000    3   32         677   7238
 19        18.0000000000000    2   28         960   6749
 20        19.0000000000000    2   34         181  24114
 21        10.0000000000000    6   25         644  -8361
  1. 重複行を検出して保存:
    python find_duplicates.py
    

出力例

Mock FITS file created: mock_event_data.fits
Found 2 duplicate rows.
Duplicate rows saved to duplicates.fits

ファイルの中身も確認しましょう。

>ftlist duplicates.fits     
                       TIME ITYP PIXE     TRIG_LP DERIV_
                                                        
  1        10.0000000000000    7    2         294  32600
  2        10.0000000000000    6   25         644  -8361

TIMEが 10.0 の部分だけが検出できていますね。


まとめ

本記事では、擬似FITSファイルの生成から重複行の検出、エンディアンの変換方法について説明しました。FITSファイルの解析では、numpypandasのエンディアンの違いに注意が必要です。必要に応じてエンディアンをリトルエンディアンに変換し、データの互換性を確保しましょう。


参考文献

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?