バイオインフォマティクスでは、遺伝子発現データやサンプル情報を扱う際に 欠損値(NaN: Not a Number) が頻繁に発生します。例えば、RNA-seqデータで特定の遺伝子の発現値が欠落していたり、臨床データで測定されていない項目があったりすることはよくあります。
Pythonの pandas ライブラリには、欠損値を効率的に処理するための機能が豊富に備わっています。本記事では、pandasを用いた欠損値の基本的な処理方法から、応用的なテクニックまで詳しく解説します。
1. pandasにおける欠損値とは?
pandasでは、欠損値(NaN)は numpy.nan
として扱われます。データフレームを作成すると、欠損値のあるセルには NaN
が自動的に入ります。
1.1 欠損値を含むデータの作成
import pandas as pd
import numpy as np
# データフレームの作成(遺伝子発現データを想定)
df = pd.DataFrame({
"Sample1": [2.5, np.nan, 5.3, 6.2],
"Sample2": [1.2, 7.9, np.nan, 5.6],
"Sample3": [3.1, 8.5, 6.1, np.nan]
}, index=["BRCA1", "TP53", "EGFR", "MYC"])
print(df)
出力
Sample1 Sample2 Sample3
BRCA1 2.5 1.2 3.1
TP53 NaN 7.9 8.5
EGFR 5.3 NaN 6.1
MYC 6.2 5.6 NaN
このように、NaN
の部分が欠損値です。
2. pandasの基本的な欠損値処理
pandasでは、欠損値を「削除」するか「補完」するのが一般的な処理方法です。
2.1 欠損値の確認
まず、データにどれだけ欠損値が含まれているかを確認する方法を紹介します。
print(df.isnull()) # 欠損値の有無をTrue/Falseで表示
print(df.isnull().sum()) # 各列の欠損値の数を表示
出力
Sample1 Sample2 Sample3
BRCA1 False False False
TP53 True False False
EGFR False True False
MYC False False True
Sample1 1
Sample2 1
Sample3 1
dtype: int64
各列に1つずつ NaN
があることがわかります。
2.2 欠損値を削除する
dropna()
を使うと、欠損値を含む行または列を削除できます。
df_dropped = df.dropna() # 欠損値を含む行を削除
print(df_dropped)
出力
Sample1 Sample2 Sample3
BRCA1 2.5 1.2 3.1
1つでも NaN
を含む行が削除されました。
列ごとに削除する場合は axis=1
を指定します。
df_dropped_col = df.dropna(axis=1)
print(df_dropped_col)
出力
Empty DataFrame
Columns: []
Index: [BRCA1, TP53, EGFR, MYC]
すべての列に NaN
が含まれていたため、空のデータフレームになってしまいました。データの損失を防ぐため、安易に dropna()
を使うのは注意が必要です。
2.3 欠損値を補完する
方法1:固定値で埋める
例えば、欠損値を 0
に置き換える場合:
df_filled = df.fillna(0)
print(df_filled)
出力
Sample1 Sample2 Sample3
BRCA1 2.5 1.2 3.1
TP53 0.0 7.9 8.5
EGFR 5.3 0.0 6.1
MYC 6.2 5.6 0.0
測定されていないデータを 0
とするのは一部のケースでは有効ですが、解析の目的に応じて慎重に選ぶ必要があります。
方法2:平均値で埋める
各列の平均値を計算し、それを欠損値に代入することも可能です。
df_filled_mean = df.fillna(df.mean())
print(df_filled_mean)
出力
Sample1 Sample2 Sample3
BRCA1 2.5 1.2 3.1
TP53 4.67 7.9 8.5
EGFR 5.3 4.9 6.1
MYC 6.2 5.6 5.9
データの分布を大きく変えずに補完できるため、統計的に妥当な方法です。
方法3:前後のデータを利用する(線形補完)
時系列データや連続した測定データでは、前後の値を使って補完する方法が有効です。
df_filled_ffill = df.fillna(method="ffill") # 前の行の値で補完
print(df_filled_ffill)
出力
Sample1 Sample2 Sample3
BRCA1 2.5 1.2 3.1
TP53 2.5 7.9 8.5
EGFR 5.3 7.9 6.1
MYC 6.2 5.6 6.1
このように、ffill
(前方向)や bfill
(後方向)を使って、欠損値を前後のデータで埋めることができます。
3. 応用:欠損値の推定
欠損値が多い場合、機械学習を使って補完する方法もあります。
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy="mean") # 平均値で補完
df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns, index=df.index)
print(df_imputed)
この方法は、より高度な補完を行いたい場合に有効です。
4. まとめ
バイオインフォマティクスでの欠損値処理は重要なステップです。適切な方法を選ぶことで、解析の精度を向上させることができます!!
dropna()
で削除する(データ損失に注意)fillna()
で固定値・平均値・前後の値を使って補完するSimpleImputer
などを活用し、より高度な補完を行う
いろんな方法があるので、どの方法を使うべきかは、データの性質と解析の目的に応じて慎重に選択することが重要ですね〜!